hashicorp/nomad · error

failed to encode passed object: %v

Error message

failed to encode passed object: %v

What it means

boltdd.Bucket.Put wraps any failure of the msgpack encoder (codec.NewEncoder with structs.MsgpackHandle) that serializes the caller-supplied value before it is written to the underlying bolt bucket. The library cannot serialize the value, so nothing is written and the underlying encode error is surfaced verbatim. It indicates the passed value (or something reachable from it) is not msgpack-encodable.

Source

Thrown at helper/boltdd/boltdd.go:315

}

// newBucket creates a new view into a bucket backed by a boltdb
// transaction.
func newBucket(b *bucketMeta, bb *bbolt.Bucket) *Bucket {
	return &Bucket{
		bm:         b,
		boltBucket: bb,
	}
}

// Put into boltdb iff it has changed since the last write.
func (b *Bucket) Put(key []byte, val interface{}) error {
	// buffer for writing serialized state to
	var buf bytes.Buffer

	// Serialize the object
	if err := codec.NewEncoder(&buf, structs.MsgpackHandle).Encode(val); err != nil {
		return fmt.Errorf("failed to encode passed object: %v", err)
	}

	// Hash for skipping unnecessary writes
	hashKey := string(key)
	hashVal := blake2b.Sum256(buf.Bytes())

	// lastHash value or nil if it hasn't been hashed yet
	lastHash := b.bm.getHash(hashKey)

	// If the hashes are equal, skip the write
	if bytes.Equal(hashVal[:], lastHash) {
		return nil
	}

	// New value: write it to the underlying boltdb
	if err := b.boltBucket.Put(key, buf.Bytes()); err != nil {
		return fmt.Errorf("failed to write data at key %s: %v", key, err)
	}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Read the wrapped %v cause to identify the unencodable field or type in val.
  2. Remove or tag (codec:'-' / msgpack omit) unencodable fields such as funcs, channels, or sync primitives from the struct.
  3. Implement a custom encoding (MarshalMsgpack or codec handles) for types the encoder cannot handle.
  4. Ensure the value passed is a concrete non-nil value whose type is registered if interfaces are involved.

Example fix

// before
b.Put([]byte("cfg"), cfg) // cfg contains stopCh chan struct{}
// after
type config struct {
    Addr string
    stopCh chan struct{} `codec:"-"` // excluded from encoding
}
b.Put([]byte("cfg"), cfg)
Defensive patterns

Strategy: validation

Validate before calling

func canMsgpackEncode(v interface{}) error {
    var buf bytes.Buffer
    return codec.NewEncoder(&buf, structs.MsgpackHandle).Encode(v)
}
if err := canMsgpackEncode(val); err != nil {
    return fmt.Errorf("value not encodable: %w", err)
}

Try / catch

if err := b.Put(key, val); err != nil {
    if strings.HasPrefix(err.Error(), "failed to encode passed object") {
        // log offending type: fmt.Sprintf("%T", val)
        return err
    }
    return err
}

Prevention

When it happens

Trigger: Calling Bucket.Put(key, val) where val's type cannot be encoded by go-msgpack: channels, funcs, or values containing them; types with no exported fields and no custom encoding; a nil pointer of an unregistered interface/oneof type; a custom MarshalMsgpack/encoding implementation returning an error.

Common situations: Passing a struct containing a func or channel field (e.g. a callback or stop channel) added during refactoring; passing types meant for JSON that msgpack rejects; upgrading hashicorp/go-msgpack and hitting stricter encoding behavior; accidentally passing a pointer to interface instead of a concrete value.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/8f0fe09747b16260. Report an issue: GitHub.