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

  1. Store only sortable scalar cursor fields (IDs, timestamps), not whole objects.
  2. If a custom JSONMarshal is set, ensure it handles every value type you pass in.
  3. Reduce the number of cursor fields or their size so the encoded token stays under maxCursorLen.
  4. 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

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


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)