go-gorm/gorm · error

integer overflow conversion uint64(%d) -> int64

Error message

integer overflow conversion uint64(%d) -> int64

What it means

UnixSecondSerializer.Value converts a stored Unix-seconds integer to time.Time when writing to the database. For unsigned inputs, values above math.MaxInt64 cannot be converted to the int64 that time.Unix requires, so the write is rejected with an overflow error instead of silently producing a wrong timestamp.

Source

Thrown at schema/serializer.go:136

// Scan implements serializer interface
func (UnixSecondSerializer) Scan(ctx context.Context, field *Field, dst reflect.Value, dbValue interface{}) (err error) {
	t := sql.NullTime{}
	if err = t.Scan(dbValue); err == nil && t.Valid {
		err = field.Set(ctx, dst, t.Time.Unix())
	}

	return
}

// Value implements serializer interface
func (UnixSecondSerializer) Value(ctx context.Context, field *Field, dst reflect.Value, fieldValue interface{}) (result interface{}, err error) {
	rv := reflect.ValueOf(fieldValue)
	switch fieldValue.(type) {
	case int, int8, int16, int32, int64:
		result = time.Unix(rv.Int(), 0).UTC()
	case uint, uint8, uint16, uint32, uint64:
		if uv := rv.Uint(); uv > math.MaxInt64 {
			err = fmt.Errorf("integer overflow conversion uint64(%d) -> int64", uv)
		} else {
			result = time.Unix(int64(uv), 0).UTC() //nolint:gosec
		}
	case *int, *int8, *int16, *int32, *int64:
		if rv.IsZero() {
			return nil, nil
		}
		result = time.Unix(rv.Elem().Int(), 0).UTC()
	case *uint, *uint8, *uint16, *uint32, *uint64:
		if rv.IsZero() {
			return nil, nil
		}
		if uv := rv.Elem().Uint(); uv > math.MaxInt64 {
			err = fmt.Errorf("integer overflow conversion uint64(%d) -> int64", uv)
		} else {
			result = time.Unix(int64(uv), 0).UTC() //nolint:gosec
		}
	default:

View on GitHub (pinned to 1d6ce99528)

Solutions

  1. Clamp or validate uint64 values to <= math.MaxInt64 before save.
  2. Investigate where the oversized value comes from — usually a bug or corrupted source data.
  3. If genuinely larger ranges are needed, store nanoseconds in a different representation (string/decimal) rather than Unix seconds.

Example fix

// before
maxVal := uint64(math.MaxUint64)
user.LoginAt = maxVal // serializer overflows

// after
if user.LoginAt > math.MaxInt64 {
    user.LoginAt = math.MaxInt64
}
Defensive patterns

Strategy: validation

Validate before calling

func safeUnixSeconds(u uint64) (int64, error) {
    if u > math.MaxInt64 {
        return 0, fmt.Errorf("unix seconds %d exceeds int64", u)
    }
    return int64(u), nil
}
// call before assigning to the serialized field

Try / catch

if err := db.Create(&user).Error; err != nil {
    if strings.Contains(err.Error(), "integer overflow conversion uint64") {
        return fmt.Errorf("timestamp field overflowed; clamp to MaxInt64 or fix source data: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: A model field tagged `gorm:"serializer:unixsecond;type:bigint"` (or plain uint64) holding a value > 9223372036854775807 — typically corrupted data, overflowed counters, or uninitialized ^uint64(0)-style defaults.

Common situations: Porting legacy data with sentinel values like ^uint64(0); arithmetic overflow before assignment; unit tests filling fields with MaxUint64 to simulate 'far future'.

Related errors


AI-assisted analysis of go-gorm/gorm@1d6ce99528 (2026-08-15). Data as JSON: /api/errors/1c5fa4e1822a61d3. Report an issue: GitHub.