If you need to handle JSON strings or streams that have multiple JSON roots the Go library does come with this functionality, but it not easily accessible. It takes a bit of fiddling with reflect.

Here is my drop-in version:

// UnmarshalMultiJSON is used to unmarshal data that contains multiple JSON
// roots.
// The destination must be a slice. Each slice member will correspond to the
// same logic as json.Unmarshal. Any whitespace between roots will be ignored.
// The error behaviour and messages have been kept as consistent as possible
// with json.Unmarshal. However, json.Unmarshal returns more specific error
// types such as json.SyntaxError that cannot be instantiated from outside of
// the json package.
// data = []byte(`{"foo":"bar"}["a", "b"]`)
// var dest []interface{}
// err := UnmarshalMultiJSON(data, &dest)
func UnmarshalMultiJSON(data []byte, dest interface{}) (err error) {
if len(data) == 0 {
return errors.New("unexpected end of JSON input")

valueOfDest := reflect.ValueOf(dest)
if !valueOfDest.IsValid() {
return errors.New("json: Unmarshal(nil)")

typeOfDest := reflect.TypeOf(dest)
if valueOfDest.Kind() != reflect.Ptr {
return fmt.Errorf("json: Unmarshal(non-pointer %s)",

if typeOfDest.Elem().Kind() != reflect.Slice {
return fmt.Errorf(
"json: cannot unmarshal object into Go value of type %s",

reader := bytes.NewReader(data)
decoder := json.NewDecoder(reader)
newSlice := reflect.New(typeOfDest.Elem()).Elem()

for decoder.More() {
singleDest := reflect.New(typeOfDest.Elem().Elem()).Interface()
err = decoder.Decode(&singleDest)

if err != nil {

newSlice = reflect.Append(newSlice, reflect.ValueOf(singleDest).Elem())