diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc
index 62592b0..d878dd2 100644
--- a/CHANGELOG.adoc
+++ b/CHANGELOG.adoc
@@ -1,5 +1,16 @@
 = changelog
 
+== from 0.4.0 to 0.4.1
+
+* fix: removed luacheck lint errors
+
+== from 0.3.0 to 0.4.0
+
+* removed unnecessary check
+* changed error handling
+** the returned error value is now a message
+** can potentially break existing code - please check your code!
+
 == from 0.2.0 to 0.3.0
 
 * fix: updated outdated README example for crockford
diff --git a/README.adoc b/README.adoc
index fab217f..69127fa 100644
--- a/README.adoc
+++ b/README.adoc
@@ -13,12 +13,14 @@ The *_from_* functions have two parameters:
 * *str* which represent the encoded string that should be decoded
 * *ignore* is an optional set of characters that should be ignored in the string, see the *_from_bit_* and *_from_hex_* examples
 
-The *_from_* functions return a string if the string can be decoded, otherwise *_nil_* and information which character caused the error.
+The *_from_* functions return a string if the string can be decoded, otherwise *_nil_* and an error message.
 
 The *_to_* functions have just one parameter:
 
 * *str* the data string that should be encoded
 
+The *_to_z85_* function can return *_nil_* and an error message, all other functions return allways the encoded string.
+
 === from_bit / to_bit
 
 Converts a byte string to a bitfield string.
@@ -98,7 +100,7 @@ basexx.from_z85( "f!$Kw" ) --> 1234
 
 == Installation
 
-To install the version 0.3.0 of basexx use LuaRocks with the following line.
+To install the version 0.4.1 of basexx use LuaRocks with the following line.
 
 ----
 luarocks install basexx
diff --git a/debian/changelog b/debian/changelog
index ae21e33..6727bac 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+lua-basexx (0.4.1+git20210823.2.b4ee13f-1) UNRELEASED; urgency=low
+
+  * New upstream snapshot.
+  * New upstream snapshot.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Sun, 17 Apr 2022 07:59:42 -0000
+
 lua-basexx (0.3-2) unstable; urgency=medium
 
   * Change Architecture: to all as it's Lua only package
diff --git a/dist/basexx-0.3.0-1.rockspec b/dist/basexx-0.3.0-1.rockspec
new file mode 100644
index 0000000..b01c805
--- /dev/null
+++ b/dist/basexx-0.3.0-1.rockspec
@@ -0,0 +1,27 @@
+package = "basexx"
+version = "0.3.0-1"
+
+description = {
+   summary  = "A base2, base16, base32, base64 and base85 library for Lua",
+   detailed = "A Lua library which provides base2(bitfield), base16(hex), base32(crockford/rfc), base64(rfc/url), base85(z85) decoding and encoding.",
+   license  = "MIT",
+   homepage = "https://github.com/aiq/basexx"
+}
+
+source = {
+   url = "https://github.com/aiq/basexx/archive/v0.3.0.tar.gz",
+   md5 = "32277d2c4564dabd0c45c9c67ec1e811",
+   dir = "basexx-0.3.0"
+}
+
+dependencies = {
+   "lua >= 5.1"
+}
+
+build = {
+   type = 'builtin',
+   modules = {
+      basexx = "lib/basexx.lua"
+   },
+   copy_directories = { "test" }
+}
diff --git a/dist/basexx-0.4.0-1.rockspec b/dist/basexx-0.4.0-1.rockspec
new file mode 100644
index 0000000..7894a04
--- /dev/null
+++ b/dist/basexx-0.4.0-1.rockspec
@@ -0,0 +1,27 @@
+package = "basexx"
+version = "0.4.0-1"
+
+description = {
+   summary  = "A base2, base16, base32, base64 and base85 library for Lua",
+   detailed = "A Lua library which provides base2(bitfield), base16(hex), base32(crockford/rfc), base64(rfc/url), base85(z85) decoding and encoding.",
+   license  = "MIT",
+   homepage = "https://github.com/aiq/basexx"
+}
+
+source = {
+   url = "https://github.com/aiq/basexx/archive/v0.4.0.tar.gz",
+   md5 = "c931e3abdb788be95c319be4fa0ac79f",
+   dir = "basexx-0.4.0"
+}
+
+dependencies = {
+   "lua >= 5.1"
+}
+
+build = {
+   type = 'builtin',
+   modules = {
+      basexx = "lib/basexx.lua"
+   },
+   copy_directories = { "test" }
+}
diff --git a/dist/basexx-0.4.1-1.rockspec b/dist/basexx-0.4.1-1.rockspec
new file mode 100644
index 0000000..59a6465
--- /dev/null
+++ b/dist/basexx-0.4.1-1.rockspec
@@ -0,0 +1,27 @@
+package = "basexx"
+version = "0.4.1-1"
+
+description = {
+   summary  = "A base2, base16, base32, base64 and base85 library for Lua",
+   detailed = "A Lua library which provides base2(bitfield), base16(hex), base32(crockford/rfc), base64(rfc/url), base85(z85) decoding and encoding.",
+   license  = "MIT",
+   homepage = "https://github.com/aiq/basexx"
+}
+
+source = {
+   url = "https://github.com/aiq/basexx/archive/v0.4.1.tar.gz",
+   md5 = "85fda02f7068183ced02d88696972e81",
+   dir = "basexx-0.4.1"
+}
+
+dependencies = {
+   "lua >= 5.1"
+}
+
+build = {
+   type = 'builtin',
+   modules = {
+      basexx = "lib/basexx.lua"
+   },
+   copy_directories = { "test" }
+}
diff --git a/dist/basexx-scm-0.rockspec b/dist/basexx-scm-0.rockspec
index 5762be6..24dee74 100644
--- a/dist/basexx-scm-0.rockspec
+++ b/dist/basexx-scm-0.rockspec
@@ -9,7 +9,8 @@ description = {
 }
 
 source = {
-   url = "..."
+   url = "https://github.com/aiq/basexx/archive/master.tar.gz",
+   dir = "basexx-master",
 }
 
 dependencies = {
diff --git a/lib/basexx.lua b/lib/basexx.lua
index 064071f..e8edfa5 100644
--- a/lib/basexx.lua
+++ b/lib/basexx.lua
@@ -2,8 +2,7 @@
 -- util functions
 --------------------------------------------------------------------------------
 
-local function divide_string( str, max, fillChar )
-   fillChar = fillChar or ""
+local function divide_string( str, max )
    local result = {}
 
    local start = 1
@@ -48,6 +47,11 @@ local function pure_from_bit( str )
             end ) )
 end
 
+local function unexpected_char_error( str, pos )
+   local c = string.sub( str, pos, pos )
+   return string.format( "unexpected character at position %d: '%s'", pos, c )
+end
+
 --------------------------------------------------------------------------------
 
 local basexx = {}
@@ -62,8 +66,8 @@ function basexx.from_bit( str, ignore )
    str = ignore_set( str, ignore )
    str = string.lower( str )
    str = str:gsub( '[ilo]', function( c ) return bitMap[ c ] end )
-   local wrong = str:match( "[^01]" )
-   if wrong then return nil, wrong end
+   local pos = string.find( str, "[^01]" )
+   if pos then return nil, unexpected_char_error( str, pos ) end
 
    return pure_from_bit( str )
 end
@@ -72,7 +76,7 @@ function basexx.to_bit( str )
    return ( str:gsub( '.', function ( c )
                local byte = string.byte( c )
                local bits = {}
-               for i = 1,8 do
+               for _ = 1,8 do
                   table.insert( bits, byte % 2 )
                   byte = math.floor( byte / 2 )
                end
@@ -86,8 +90,8 @@ end
 
 function basexx.from_hex( str, ignore )
    str = ignore_set( str, ignore )
-   local wrong = str:match( "[^%x]" )
-   if wrong then return nil, wrong end
+   local pos = string.find( str, "[^%x]" )
+   if pos then return nil, unexpected_char_error( str, pos ) end
 
    return ( str:gsub( '..', function ( cc )
                return string.char( tonumber( cc, 16 ) )
@@ -110,8 +114,8 @@ local function from_basexx( str, alphabet, bits )
       local c = string.sub( str, i, i )
       if c ~= '=' then
          local index = string.find( alphabet, c, 1, true )
-         if not index or c == "$" then
-            return nil, c
+         if not index then
+            return nil, unexpected_char_error( str, i )
          end
          table.insert( result, number_to_bit( index - 1, bits ) )
       end
@@ -127,7 +131,7 @@ local function to_basexx( str, alphabet, bits, pad )
 
    local chunks = divide_string( bitString, bits )
    local result = {}
-   for key,value in ipairs( chunks ) do
+   for _,value in ipairs( chunks ) do
       if ( #value < bits ) then
          value = value .. string.rep( '0', bits - #value )
       end
@@ -212,6 +216,10 @@ end
 --
 --------------------------------------------------------------------------------
 
+local function length_error( len, d )
+   return string.format( "invalid length: %d - must be a multiple of %d", len, d )
+end
+
 local z85Decoder = { 0x00, 0x44, 0x00, 0x54, 0x53, 0x52, 0x48, 0x00,
                      0x4B, 0x4C, 0x46, 0x41, 0x00, 0x3F, 0x3E, 0x45, 
                      0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
@@ -227,14 +235,18 @@ local z85Decoder = { 0x00, 0x44, 0x00, 0x54, 0x53, 0x52, 0x48, 0x00,
 
 function basexx.from_z85( str, ignore )
    str = ignore_set( str, ignore )
-   if ( #str % 5 ) ~= 0 then return nil, #str % 5 end
+   if ( #str % 5 ) ~= 0 then
+      return nil, length_error( #str, 5 )
+   end
 
    local result = {}
 
    local value = 0
    for i = 1, #str do
       local index = string.byte( str, i ) - 31
-      if index < 1 or index >= #z85Decoder then return nil, index end
+      if index < 1 or index >= #z85Decoder then
+         return nil, unexpected_char_error( str, i )
+      end
       value = ( value * 85 ) + z85Decoder[ index ]
       if ( i % 5 ) == 0 then
          local divisor = 256 * 256 * 256
@@ -256,7 +268,9 @@ local z85Encoder = "0123456789"..
                    ".-:+=^!/*?&<>()[]{}@%$#"
 
 function basexx.to_z85( str )
-   if ( #str % 4 ) ~= 0 then return nil, #str, 4 end
+   if ( #str % 4 ) ~= 0 then
+      return nil, length_error( #str, 4 )
+   end
 
    local result = {}
 
diff --git a/test/base32_spec.lua b/test/base32_spec.lua
index ed7b248..b8c1733 100644
--- a/test/base32_spec.lua
+++ b/test/base32_spec.lua
@@ -18,7 +18,7 @@ describe( "should handle base32(rfc3548) strings", function()
    it ( "should handle wrong characters without a crash", function()
       local res, err = basexx.from_base32( "MS$DF" )
       assert.is.falsy( res )
-      assert.is.same( "$", err )
+      assert.is.same( "unexpected character at position 3: '$'", err )
    end)
 
 end)
diff --git a/test/base64_spec.lua b/test/base64_spec.lua
index 52d1ef5..c9d246a 100644
--- a/test/base64_spec.lua
+++ b/test/base64_spec.lua
@@ -65,7 +65,7 @@ describe( "should handle base64 strings", function()
    it( "should handle wrong characters without a crash", function()
       local res, err = basexx.from_base64( "TW`Fu" )
       assert.is.falsy( res )
-      assert.is.same( "`", err )
+      assert.is.same( "unexpected character at position 3: '`'", err )
    end)
 
 end)
diff --git a/test/bit_spec.lua b/test/bit_spec.lua
index f21ead0..f275844 100644
--- a/test/bit_spec.lua
+++ b/test/bit_spec.lua
@@ -24,7 +24,7 @@ describe( "should handle bitfields strings", function()
    it( "should handle wrong characters without a crash", function()
       local res, err = basexx.from_bit( "o1oo*ooo1*o1oo*oo11" )
       assert.is.falsy( res )
-      assert.is.same( "*", err )
+      assert.is.same( "unexpected character at position 5: '*'", err )
    end)
 
 end)
diff --git a/test/crockford_spec.lua b/test/crockford_spec.lua
index 38e983b..2651d45 100644
--- a/test/crockford_spec.lua
+++ b/test/crockford_spec.lua
@@ -19,10 +19,10 @@ describe( "should handle base32(crockford) strings", function()
       assert.is.same( "foo", basexx.from_crockford( "CSQPY\n", "\n" ) )
    end)
 
-   it( "should allow to ignore characters without a crash", function()
+   it( "should handle wrong characters without a crash", function()
       local res, err = basexx.from_crockford( "CSQ%PY" )
       assert.is.falsy( res )
-      assert.is.same( "%", err )
+      assert.is.same( "unexpected character at position 4: '%'", err )
    end)
 
 end)
diff --git a/test/hex_spec.lua b/test/hex_spec.lua
index 39a0057..4ba4e50 100644
--- a/test/hex_spec.lua
+++ b/test/hex_spec.lua
@@ -22,7 +22,7 @@ describe( "should handle hex strings", function()
    it( "should handle wrong characters without a crash", function()
       local res, err = basexx.from_hex( "4865-6c6c" )
       assert.is.falsy( res )
-      assert.is.same( "-", err )
+      assert.is.same( "unexpected character at position 5: '-'", err )
    end)
 
 end)
diff --git a/test/z85_spec.lua b/test/z85_spec.lua
index a2a9dc5..37ad4ee 100644
--- a/test/z85_spec.lua
+++ b/test/z85_spec.lua
@@ -20,4 +20,22 @@ describe( "should handle ZeroMQ base85 strings", function()
       assert.is.same( "1234", basexx.from_z85( "'f!$Kw'\n", "'\n" ) )
    end)
 
+   it( "should handle wrong input lenght without a crash", function()
+      local res, err = basexx.from_z85( "abcdefghi" )
+      assert.is.falsy( res )
+      assert.is.same( err, "invalid length: 9 - must be a multiple of 5" )
+
+      res, err = basexx.to_z85( "abcdefghi" )
+      assert.is.falsy( res )
+      assert.is.same( err, "invalid length: 9 - must be a multiple of 4" )
+   end)
+
+   it( "should handle wrong characters without a crash", function()
+      local c = string.char( 140 )
+      local res, err = basexx.from_z85( "f"..c.."$Kw" )
+      assert.is.falsy( res )
+      local msg = string.format( "unexpected character at position 2: '%s'", c )
+      assert.is.same( err, msg )
+   end)
+
 end)