hashicorp/nomad · error

bitmap must be byte aligned

Error message

bitmap must be byte aligned

What it means

NewBitmap only supports sizes that are multiples of 8 (byte aligned), since the Bitmap is stored as a raw []byte and a non-aligned bit count would overflow the last byte. Any size where size&7 != 0 is rejected with this error. This is an internal invariant of Nomad's port bitmap implementation.

Source

Thrown at nomad/structs/bitmap.go:20

// SPDX-License-Identifier: BUSL-1.1

package structs

import (
	"fmt"
	"slices"
)

// 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 {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Round the requested size up to the next multiple of 8 before calling NewBitmap (size = (size + 7) & ^uint(7)).
  2. Compute port-range sizes as (to - from + 1) and align to 8.
  3. If only the exact bit count matters, allocate the aligned size and ignore trailing bits.

Example fix

// before
bm, err := structs.NewBitmap(uint(len(ports))) // len=10 -> error
// after
size := uint(len(ports))
size = (size + 7) & ^uint(7)
bm, err := structs.NewBitmap(size)
Defensive patterns

Strategy: validation

Validate before calling

size := uint(n)
if size&7 != 0 {
    size = (size + 7) & ^uint(7)
}
bm, err := structs.NewBitmap(size)

Try / catch

bm, err := structs.NewBitmap(size)
if err != nil && strings.Contains(err.Error(), "byte aligned") {
    bm, err = structs.NewBitmap((size + 7) & ^uint(7))
}

Prevention

When it happens

Trigger: Calling structs.NewBitmap(size) where size is not a multiple of 8 - e.g. NewBitmap(10), or getDynamicPortsPrecise computing a range whose length isn't byte aligned.

Common situations: Custom resource math producing port counts like 1001; tests constructing oddly sized bitmaps; plugin code allocating bitmap capacity from arbitrary range lengths.

Related errors


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