diff --git a/rlp/decode.go b/rlp/decode.go
index 3546f61068c408484a91deef260380835db1cdd7..7d95af02bc7d699981e9df649f4af67179aea917 100644
--- a/rlp/decode.go
+++ b/rlp/decode.go
@@ -72,6 +72,15 @@ func Decode(r io.Reader, val interface{}) error {
 	return NewStream(r).Decode(val)
 }
 
+type decodeError struct {
+	msg string
+	typ reflect.Type
+}
+
+func (err decodeError) Error() string {
+	return fmt.Sprintf("rlp: %s for %v", err.msg, err.typ)
+}
+
 func makeNumDecoder(typ reflect.Type) decoder {
 	kind := typ.Kind()
 	switch {
@@ -85,8 +94,11 @@ func makeNumDecoder(typ reflect.Type) decoder {
 }
 
 func decodeInt(s *Stream, val reflect.Value) error {
-	num, err := s.uint(val.Type().Bits())
-	if err != nil {
+	typ := val.Type()
+	num, err := s.uint(typ.Bits())
+	if err == errUintOverflow {
+		return decodeError{"input string too long", typ}
+	} else if err != nil {
 		return err
 	}
 	val.SetInt(int64(num))
@@ -94,8 +106,11 @@ func decodeInt(s *Stream, val reflect.Value) error {
 }
 
 func decodeUint(s *Stream, val reflect.Value) error {
-	num, err := s.uint(val.Type().Bits())
-	if err != nil {
+	typ := val.Type()
+	num, err := s.uint(typ.Bits())
+	if err == errUintOverflow {
+		return decodeError{"input string too big", typ}
+	} else if err != nil {
 		return err
 	}
 	val.SetUint(num)
@@ -177,7 +192,7 @@ func decodeList(s *Stream, val reflect.Value, elemdec decoder, maxelem int) erro
 	i := 0
 	for {
 		if i > maxelem {
-			return fmt.Errorf("rlp: input List has more than %d elements", maxelem)
+			return decodeError{"input list has too many elements", val.Type()}
 		}
 		if val.Kind() == reflect.Slice {
 			// grow slice if necessary
@@ -228,8 +243,6 @@ func decodeByteSlice(s *Stream, val reflect.Value) error {
 	return err
 }
 
-var errStringDoesntFitArray = errors.New("rlp: string value doesn't fit into target array")
-
 func decodeByteArray(s *Stream, val reflect.Value) error {
 	kind, size, err := s.Kind()
 	if err != nil {
@@ -238,14 +251,14 @@ func decodeByteArray(s *Stream, val reflect.Value) error {
 	switch kind {
 	case Byte:
 		if val.Len() == 0 {
-			return errStringDoesntFitArray
+			return decodeError{"input string too big", val.Type()}
 		}
 		bv, _ := s.Uint()
 		val.Index(0).SetUint(bv)
 		zero(val, 1)
 	case String:
 		if uint64(val.Len()) < size {
-			return errStringDoesntFitArray
+			return decodeError{"input string too big", val.Type()}
 		}
 		slice := val.Slice(0, int(size)).Interface().([]byte)
 		if err := s.readFull(slice); err != nil {
@@ -295,7 +308,7 @@ func makeStructDecoder(typ reflect.Type) (decoder, error) {
 			}
 		}
 		if err = s.ListEnd(); err == errNotAtEOL {
-			err = errors.New("rlp: input List has too many elements")
+			err = decodeError{"input list has too many elements", typ}
 		}
 		return err
 	}
@@ -476,6 +489,8 @@ func (s *Stream) Bytes() ([]byte, error) {
 	}
 }
 
+var errUintOverflow = errors.New("rlp: uint overflow")
+
 // Uint reads an RLP string of up to 8 bytes and returns its contents
 // as an unsigned integer. If the input does not contain an RLP string, the
 // returned error will be ErrExpectedString.
@@ -494,7 +509,7 @@ func (s *Stream) uint(maxbits int) (uint64, error) {
 		return uint64(s.byteval), nil
 	case String:
 		if size > uint64(maxbits/8) {
-			return 0, fmt.Errorf("rlp: string is larger than %d bits", maxbits)
+			return 0, errUintOverflow
 		}
 		return s.readUint(byte(size))
 	default:
diff --git a/rlp/decode_test.go b/rlp/decode_test.go
index d82ccbd6a3db2a75cd6ef0cc7beb4178dcd5b8e5..3b60234dd9f4f89a3f0bbce8432307a3532c20fe 100644
--- a/rlp/decode_test.go
+++ b/rlp/decode_test.go
@@ -3,7 +3,6 @@ package rlp
 import (
 	"bytes"
 	"encoding/hex"
-	"errors"
 	"fmt"
 	"io"
 	"math/big"
@@ -87,7 +86,7 @@ func TestStreamErrors(t *testing.T) {
 		{"81", calls{"Bytes"}, io.ErrUnexpectedEOF},
 		{"81", calls{"Uint"}, io.ErrUnexpectedEOF},
 		{"BFFFFFFFFFFFFFFF", calls{"Bytes"}, io.ErrUnexpectedEOF},
-		{"89000000000000000001", calls{"Uint"}, errors.New("rlp: string is larger than 64 bits")},
+		{"89000000000000000001", calls{"Uint"}, errUintOverflow},
 		{"00", calls{"List"}, ErrExpectedList},
 		{"80", calls{"List"}, ErrExpectedList},
 		{"C0", calls{"List", "Uint"}, EOL},
@@ -181,7 +180,7 @@ type decodeTest struct {
 	input string
 	ptr   interface{}
 	value interface{}
-	error error
+	error string
 }
 
 type simplestruct struct {
@@ -214,8 +213,8 @@ var decodeTests = []decodeTest{
 	{input: "820505", ptr: new(uint32), value: uint32(0x0505)},
 	{input: "83050505", ptr: new(uint32), value: uint32(0x050505)},
 	{input: "8405050505", ptr: new(uint32), value: uint32(0x05050505)},
-	{input: "850505050505", ptr: new(uint32), error: errors.New("rlp: string is larger than 32 bits")},
-	{input: "C0", ptr: new(uint32), error: ErrExpectedString},
+	{input: "850505050505", ptr: new(uint32), error: "rlp: input string too big for uint32"},
+	{input: "C0", ptr: new(uint32), error: ErrExpectedString.Error()},
 
 	// slices
 	{input: "C0", ptr: new([]int), value: []int{}},
@@ -224,7 +223,7 @@ var decodeTests = []decodeTest{
 	// arrays
 	{input: "C0", ptr: new([5]int), value: [5]int{}},
 	{input: "C50102030405", ptr: new([5]int), value: [5]int{1, 2, 3, 4, 5}},
-	{input: "C6010203040506", ptr: new([5]int), error: errors.New("rlp: input List has more than 5 elements")},
+	{input: "C6010203040506", ptr: new([5]int), error: "rlp: input list has too many elements for [5]int"},
 
 	// byte slices
 	{input: "01", ptr: new([]byte), value: []byte{1}},
@@ -232,7 +231,7 @@ var decodeTests = []decodeTest{
 	{input: "8D6162636465666768696A6B6C6D", ptr: new([]byte), value: []byte("abcdefghijklm")},
 	{input: "C0", ptr: new([]byte), value: []byte{}},
 	{input: "C3010203", ptr: new([]byte), value: []byte{1, 2, 3}},
-	{input: "C3820102", ptr: new([]byte), error: errors.New("rlp: string is larger than 8 bits")},
+	{input: "C3820102", ptr: new([]byte), error: "rlp: input string too big for uint8"},
 
 	// byte arrays
 	{input: "01", ptr: new([5]byte), value: [5]byte{1}},
@@ -240,9 +239,9 @@ var decodeTests = []decodeTest{
 	{input: "850102030405", ptr: new([5]byte), value: [5]byte{1, 2, 3, 4, 5}},
 	{input: "C0", ptr: new([5]byte), value: [5]byte{}},
 	{input: "C3010203", ptr: new([5]byte), value: [5]byte{1, 2, 3, 0, 0}},
-	{input: "C3820102", ptr: new([5]byte), error: errors.New("rlp: string is larger than 8 bits")},
-	{input: "86010203040506", ptr: new([5]byte), error: errStringDoesntFitArray},
-	{input: "850101", ptr: new([5]byte), error: io.ErrUnexpectedEOF},
+	{input: "C3820102", ptr: new([5]byte), error: "rlp: input string too big for uint8"},
+	{input: "86010203040506", ptr: new([5]byte), error: "rlp: input string too big for [5]uint8"},
+	{input: "850101", ptr: new([5]byte), error: io.ErrUnexpectedEOF.Error()},
 
 	// byte array reuse (should be zeroed)
 	{input: "850102030405", ptr: &sharedByteArray, value: [5]byte{1, 2, 3, 4, 5}},
@@ -255,25 +254,25 @@ var decodeTests = []decodeTest{
 	// zero sized byte arrays
 	{input: "80", ptr: new([0]byte), value: [0]byte{}},
 	{input: "C0", ptr: new([0]byte), value: [0]byte{}},
-	{input: "01", ptr: new([0]byte), error: errStringDoesntFitArray},
-	{input: "8101", ptr: new([0]byte), error: errStringDoesntFitArray},
+	{input: "01", ptr: new([0]byte), error: "rlp: input string too big for [0]uint8"},
+	{input: "8101", ptr: new([0]byte), error: "rlp: input string too big for [0]uint8"},
 
 	// strings
 	{input: "00", ptr: new(string), value: "\000"},
 	{input: "8D6162636465666768696A6B6C6D", ptr: new(string), value: "abcdefghijklm"},
-	{input: "C0", ptr: new(string), error: ErrExpectedString},
+	{input: "C0", ptr: new(string), error: ErrExpectedString.Error()},
 
 	// big ints
 	{input: "01", ptr: new(*big.Int), value: big.NewInt(1)},
 	{input: "89FFFFFFFFFFFFFFFFFF", ptr: new(*big.Int), value: veryBigInt},
 	{input: "10", ptr: new(big.Int), value: *big.NewInt(16)}, // non-pointer also works
-	{input: "C0", ptr: new(*big.Int), error: ErrExpectedString},
+	{input: "C0", ptr: new(*big.Int), error: ErrExpectedString.Error()},
 
 	// structs
 	{input: "C0", ptr: new(simplestruct), value: simplestruct{0, ""}},
 	{input: "C105", ptr: new(simplestruct), value: simplestruct{5, ""}},
 	{input: "C50583343434", ptr: new(simplestruct), value: simplestruct{5, "444"}},
-	{input: "C3010101", ptr: new(simplestruct), error: errors.New("rlp: input List has too many elements")},
+	{input: "C3010101", ptr: new(simplestruct), error: "rlp: input list has too many elements for rlp.simplestruct"},
 	{
 		input: "C501C302C103",
 		ptr:   new(recstruct),
@@ -312,12 +311,12 @@ func runTests(t *testing.T, decode func([]byte, interface{}) error) {
 			continue
 		}
 		err = decode(input, test.ptr)
-		if err != nil && test.error == nil {
+		if err != nil && test.error == "" {
 			t.Errorf("test %d: unexpected Decode error: %v\ndecoding into %T\ninput %q",
 				i, err, test.ptr, test.input)
 			continue
 		}
-		if test.error != nil && fmt.Sprint(err) != fmt.Sprint(test.error) {
+		if test.error != "" && fmt.Sprint(err) != test.error {
 			t.Errorf("test %d: Decode error mismatch\ngot  %v\nwant %v\ndecoding into %T\ninput %q",
 				i, err, test.error, test.ptr, test.input)
 			continue