gofiber/fiber · error
paginate: failed to encode cursor values
Error message
paginate: failed to encode cursor values
What it means
Returned by middleware/paginate.PageInfo.SetNextCursor when the cursor value map cannot be JSON-marshaled, or when the resulting base64 cursor exceeds maxCursorLen. It wraps the underlying marshal error via double %w so errors.Is(err, ErrCursorEncode) matches while the cause is still reachable. Cursors must stay small and serializable to be safe in URLs.
Solutions
- Store only sortable scalar cursor fields (IDs, timestamps), not whole objects.
- If a custom JSONMarshal is set, ensure it handles every value type you pass in.
- Reduce the number of cursor fields or their size so the encoded token stays under maxCursorLen.
- Handle the error in your resolver: fail the request rather than continuing without a cursor.
Example fix
// before
page.SetNextCursor(map[string]any{"row": bigStructWithChan})
// after
page.SetNextCursor(map[string]any{
"id": row.ID,
"updated_at": row.UpdatedAt.UnixNano(),
}) Defensive patterns
Strategy: validation
Validate before calling
func safeCursor(values map[string]any) error {
if _, err := json.Marshal(values); err != nil {
return paginate.ErrCursorEncode
}
return nil
} Try / catch
if err := page.SetNextCursor(values); err != nil {
if errors.Is(err, paginate.ErrCursorEncode) {
// drop NextCursor and return a page without a cursor, or fail the request
}
return err
} Prevention
- Put only scalar sort fields (id, timestamp) in cursors, never whole objects.
- Ensure a custom JSONMarshal handles every value type used.
- Keep cursor size bounded; large cursors risk exceeding URL limits.
When it happens
Trigger: Calling SetNextCursor with a map containing values that cannot be JSON-marshaled (channels, funcs, unexported-field structs, cyclic refs) or a map whose encoded form is too large for a cursor token.
Common situations: Storing complex domain objects or binary blobs in the cursor instead of just sort keys/IDs; a marshaler (Config.JSONMarshal) that rejects a field type; cursor values growing unbounded as the dataset shape changes.
Related errors
- : cursor token exceeds maximum length ( )
- %w: %w
- cache: failed to marshal key
- cache: failed to unmarshal key
- failed to decode session data
AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11).
Data as JSON: /api/errors/933962d255ef70be.
Report an issue: GitHub.
Appendix: source
Thrown at middleware/paginate/page_info.go:15
package paginate
import (
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"net/url"
"slices"
"github.com/gofiber/utils/v2"
)
// ErrCursorEncode is returned when cursor values cannot be encoded.
var ErrCursorEncode = errors.New("paginate: failed to encode cursor values")
// SortOrder represents sort order.
type SortOrder string
const (
ASC SortOrder = "asc"
DESC SortOrder = "desc"
)
// SortField represents a sort field with direction.
type SortField struct {
Field string `json:"field"`
Order SortOrder `json:"order"`
}
// SortOrderFromString returns a SortOrder from a string (case-insensitive).
func SortOrderFromString(s string) SortOrder {
if utils.EqualFold(s, "desc") {View on GitHub (pinned to a105acad6c)