gofiber/fiber · error
failed to encode data
Error message
failed to encode data: %w
What it means
Thrown by saveSessionWithContext when the session's in-memory data map cannot be gob-encoded before being written to the Storage backend. The %w wraps the underlying gob.Encoder error, which names the offending type or value. This is the top-level error a caller of Save()/saveSessionWithContext observes; the sibling error 202 is the same root cause surfaced from the lower-level encodeSessionData.
Solutions
- Inspect the wrapped error — gob names the unencodable type (e.g. gob: type not registered for interface: main.Foo).
- Call gob.Register(YourType{}) in an init() for every custom struct stored in the session.
- Avoid storing channels, funcs, complex numbers, or unregistered interface values; store primitive/serializable representations instead.
- If you must store dynamic types, wrap them in a concrete registered struct.
Example fix
// before
sess.Set("user", User{Name: "x", Conn: someChan})
sess.Save() // -> failed to encode data: gob: unsupported type
// after (init)
func init() { gob.Register(User{}) } Defensive patterns
Strategy: validation
Validate before calling
// Run before storing custom types in the session.
func registerSessionTypes() {
gob.Register(MyStruct{})
gob.Register(&MyStruct{})
gob.Register(map[string]any{})
}
func isGobEncodable(v any) error {
switch reflect.TypeOf(v).Kind() {
case reflect.Chan, reflect.Func, reflect.Complex64, reflect.Complex128, reflect.UnsafePointer:
return fmt.Errorf("type %T is not gob-encodable", v)
}
return nil
} Type guard
func isStorableInSession(v any) bool {
if v == nil { return true }
switch reflect.TypeOf(v).Kind() {
case reflect.Chan, reflect.Func, reflect.Complex64, reflect.Complex128:
return false
}
return true
} Try / catch
if err := sess.Save(); err != nil {
// a failed encode usually means a bad value type; log and drop the value
log.Printf("session save failed: %v", err)
sess.Destroy()
} Prevention
- gob.Register every custom struct type at program init, before any session is touched.
- Never store channels, funcs, or complex numbers in the session.
- Prefer storing simple structs / primitives rather than map[string]any with dynamic concrete types.
- Add a unit test that round-trips every value type you intend to store through gob encode+decode.
When it happens
Trigger: Calling session.Save() (or relying on the middleware's auto-save) while s.data.Data holds a value gob cannot encode: a channel, func, complex64/128, an interface{} whose concrete type was not registered with gob.Register, a struct containing such fields, or a value with a cycle gob refuses.
Common situations: Storing a custom struct in the session without calling gob.Register at init; storing map[string]any with arbitrarily-typed values whose concrete types gob does not know about; storing closures/callbacks; upgrading Fiber and storing newly-typed values without registering them.
Related errors
- failed to encode session data
- failed to decode session data
- failed to decode session data
- fiber: failed to encode shared state
- cache: failed to marshal key
AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11).
Data as JSON: /api/errors/4ca824aa3fbf868a.
Report an issue: GitHub.
Appendix: source
Thrown at middleware/session/session.go:399
}
s.mu.Lock()
defer s.mu.Unlock()
// Set idleTimeout if not already set
if s.idleTimeout <= 0 {
s.idleTimeout = s.config.IdleTimeout
}
// Update client cookie
s.setSession()
// Encode session data
s.data.RLock()
encodedBytes, err := s.encodeSessionData()
s.data.RUnlock()
if err != nil {
return fmt.Errorf("failed to encode data: %w", err)
}
// Pass copied bytes with session id to provider
return s.config.Storage.SetWithContext(ctx, s.id, encodedBytes, s.idleTimeout)
}
// Keys retrieves all keys in the current session.
//
// Returns:
// - []any: A slice of all keys in the session.
//
// Usage:
//
// keys := s.Keys()
func (s *Session) Keys() []any {
if s.data == nil {
return []any{}
}View on GitHub (pinned to a105acad6c)