hashicorp/nomad · error

can't copy nil Bitmap

Error message

can't copy nil Bitmap

What it means

Bitmap.Copy refuses to copy a nil Bitmap: a nil receiver has no backing bytes and copying it is treated as a programming error rather than silently returning nil. The method checks b == nil and returns this error so callers distinguish 'no data' from 'copy of empty data'.

Source

Thrown at nomad/structs/bitmap.go:29

// Bitmap is a simple uncompressed bitmap
type Bitmap []byte

// NewBitmap returns a bitmap with up to size indexes
func NewBitmap(size uint) (Bitmap, error) {
	if size == 0 {
		return nil, fmt.Errorf("bitmap must be positive size")
	}
	if size&7 != 0 {
		return nil, fmt.Errorf("bitmap must be byte aligned")
	}
	b := make([]byte, size>>3)
	return Bitmap(b), nil
}

// Copy returns a copy of the Bitmap
func (b Bitmap) Copy() (Bitmap, error) {
	if b == nil {
		return nil, fmt.Errorf("can't copy nil Bitmap")
	}

	raw := make([]byte, len(b))
	copy(raw, b)
	return Bitmap(raw), nil
}

// Size returns the size of the bitmap
func (b Bitmap) Size() uint {
	return uint(len(b) << 3)
}

// Set is used to set the given index of the bitmap
func (b Bitmap) Set(idx uint) {
	bucket := idx >> 3
	mask := byte(1 << (idx & 7))
	b[bucket] |= mask
}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Initialize the Bitmap with NewBitmap before copying.
  2. Guard the call: if b == nil { return nil, nil } at the call site.
  3. Ensure NetworkResource objects were built through Nomad's normal port-allocation paths, which populate the bitmap.
  4. In tests, construct the bitmap explicitly instead of relying on zero values.

Example fix

// before
net.Ports.Copy()
// after
if net.Ports == nil {
    net.Ports, err = structs.NewBitmap(1024)
    if err != nil { return err }
}
copy, err := net.Ports.Copy()
Defensive patterns

Strategy: type-guard

Validate before calling

if b == nil {
    b, err = structs.NewBitmap(1024)
    if err != nil { return err }
}

Type guard

func nonNilBitmap(b structs.Bitmap) (structs.Bitmap, error) {
    if b == nil {
        return structs.NewBitmap(1024)
    }
    return b, nil
}

Try / catch

copy, err := b.Copy()
if err != nil && strings.Contains(err.Error(), "nil Bitmap") {
    // treat as uninitialized; initialize or skip
}

Prevention

When it happens

Trigger: Calling Copy() on a Bitmap variable that was never initialized (declared but not returned from NewBitmap), commonly via getDynamicPortsPrecise on a NetworkResource whose Ports bitmap field is nil.

Common situations: Deserialized NetworkResource structs missing the internal bitmap (e.g. built by older code paths or hand-constructed in tests); copying a Bitmap from a struct field that was never populated.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/e8274ba1e54d1158. Report an issue: GitHub.