Skip to content

Extract() fails on integer JSON values at signed 64-bit maximum #4016

Closed

Description

@elfosardo

What happened?

Description
Result.Extract() cannot unmarshal valid JSON integers at signed 64-bit maximum (9223372036854775807) into int / int64 fields.

This shows up in Ironic BIOS settings (nodes.ListBIOSSettings with detail=true). Vendors such as Cisco return integer schema bounds at int64 max (CoreDisableMask_, SgxEpoch, SgxLePubKeyHash*). Gophercloud then returns:

json: cannot unmarshal number 9223372036854776000 into Go struct field BIOSSetting.bios.upper_bound of type int

The original JSON contains 9223372036854775807, not 9223372036854776000. One overflowing bound fails the entire BIOS list, so clients cannot read or apply any other setting.

This is the same class of bug as #209: Request() decodes JSONResponse into any, so numbers become float64. ExtractInto() re-marshals that body and unmarshals into the typed struct. int64 max cannot be represented exactly as float64 and is rounded to 9223372036854776000, which then does not fit in int.

Changing BIOSSetting.UpperBound from *int to *int64 does not fix this. The precision is already lost before the typed field is filled.

How to reproduce

Call:

nodes.ListBIOSSettings(ctx, client, nodeID, nodes.ListBIOSSettingsOpts{Detail: true}).Extract()

against a response that includes:

{
  "bios": [
    {
      "name": "CoreDisableMask_0_0",
      "value": "0",
      "attribute_type": "Integer",
      "lower_bound": 0,
      "upper_bound": 9223372036854775807,
      "read_only": false
    }
  ]
}

Expected behavior
Extract() returns the BIOS settings. UpperBound is 9223372036854775807 on 64-bit (math.MaxInt).

Actual behavior
Extract() fails with the unmarshal error above. No settings are returned.

Suggested fix
Use json.Decoder.UseNumber() when decoding JSON into any in ProviderClient.Request() (and the equivalent path in pagination.PageResultFrom). UseNumber() only changes decoding into interface{}; typed structs are unchanged. json.Number re-marshals with the original digits, so Extract() can fill int / int64 fields.

A value larger than int64 would still fail Extract(). That is separate from this precision bug.

Environment
gophercloud/v2 (current main)
Ironic /v1/nodes//bios?detail=true
Hardware example: Cisco UCS C880 BIOS attribute registry 4.0.2

Version

v2 (current)

Activity

  1. added theissue type on Sep 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions