Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for NGINX By James Joyner IV · · 9 min read

NGINX Error Guide: 'could not build server_names_hash' Bucket Size Overflow

Fix the NGINX 'could not build server_names_hash' startup error by tuning server_names_hash_bucket_size and server_names_hash_max_size correctly.

  • #nginx
  • #troubleshooting
  • #errors
  • #config

Exact Error Message

When NGINX fails to start or reload, you will typically see this in the output of nginx -t or in the service logs:

nginx: [emerg] could not build server_names_hash, you should increase server_names_hash_bucket_size: 32
nginx: configuration file /etc/nginx/nginx.conf test failed

The same message also appears in the error log, usually with a timestamp and worker PID when NGINX attempts to load configuration:

2026/06/27 09:14:52 [emerg] 21873#21873: could not build server_names_hash, you should increase server_names_hash_bucket_size: 32

The key phrase is could not build server_names_hash, followed by a directive name and a number. Sometimes the message references server_names_hash_max_size instead, depending on which limit NGINX hit first.

What the Error Means

NGINX stores all of your server_name values in an internal hash table so it can match incoming Host headers to the correct virtual server very quickly. This hash table is governed by two directives:

  • server_names_hash_bucket_size controls the size of each individual bucket in the hash. It defaults to 32, 64, or 128 bytes depending on your CPU cache line size.
  • server_names_hash_max_size controls the maximum total number of buckets the hash can grow to. It defaults to 512.

When NGINX builds the hash at startup, it tries to fit every server_name entry into this structure. If a single server_name is too long to fit in one bucket, NGINX cannot build the hash and aborts with could not build server_names_hash, you should increase server_names_hash_bucket_size. If the total number of names exceeds what the table can hold, you instead get a hint to increase server_names_hash_max_size.

The number printed at the end (for example : 32) is the current bucket size in bytes. NGINX is telling you the limit it hit, not the value you need. This is purely a startup-time configuration validation error: no traffic is served while the configuration is invalid.

Common Causes

Several situations push you past the default limits:

  • Long domain names. A single long FQDN such as a multi-segment subdomain (api.staging.internal.eu-west-1.example-corporation.com) can exceed the 32-byte default bucket size on its own.
  • Wildcard and regex server names. Entries like ~^(www\.)?(?<domain>.+)$ or long wildcard patterns consume more hash space than plain hostnames.
  • Many server_name aliases. Listing dozens of hostnames on one server block, or running hundreds of virtual hosts, can overflow server_names_hash_max_size.
  • Migrated or templated configs. Auto-generated configs from tools like Certbot, Ansible, or ingress controllers often pack many aliases into one directive.
  • A low explicit value. Someone may have hard-coded server_names_hash_bucket_size 32; in nginx.conf, leaving no headroom.

How to Reproduce the Error

You can reproduce this reliably on a test instance. Create a server block with a server_name longer than the default bucket size, then validate the configuration. The following is illustrative config content (do not apply it to production):

server {
    listen 80;
    server_name a-deliberately-very-long-hostname-that-exceeds-thirty-two-bytes.example.com;
}

Running a configuration test against a config containing this block produces the could not build server_names_hash error because the single name does not fit in a 32-byte bucket. Adding many additional aliases to the same server_name line instead triggers the server_names_hash_max_size variant of the message.

Diagnostic Commands

Start by confirming the error and gathering context. All of these commands are read-only and safe to run on a live host.

Test the active configuration and surface the exact failing message:

sudo nginx -t

Dump the fully resolved configuration, including all included files, so you can see every server_name NGINX actually loads:

sudo nginx -T

Search that resolved output for long or numerous server names that may be overflowing the hash:

sudo nginx -T | grep -E "server_name" | sort | uniq -c | sort -rn

Inspect the service logs for the timestamped [emerg] line and recent reload attempts:

sudo journalctl -u nginx --no-pager -n 50

Confirm whether NGINX is actually listening (after a failed reload, the old process may still be running on the configured ports):

sudo ss -ltnp | grep nginx

Verify that the site responds with the expected host once the configuration is valid:

curl -I -H "Host: example.com" http://127.0.0.1/

If the affected server blocks use TLS, confirm the certificate and SNI hostname resolve correctly:

openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | openssl x509 -noout -subject

Step-by-Step Resolution

The fix is to raise the relevant hash limit in the http context of your main configuration file, then validate and reload.

1. Identify which limit you hit. Read the error carefully. If it mentions server_names_hash_bucket_size, you have a single name that is too long. If it mentions server_names_hash_max_size, you have too many names overall. Use the nginx -T diagnostic above to pinpoint the offending entries.

2. Open the main configuration. Edit /etc/nginx/nginx.conf with your preferred text editor (for example vi, nano, or vim). The directives must go inside the http { ... } block, not inside an individual server block.

3. Set an appropriate bucket size. server_names_hash_bucket_size must be a multiple of your CPU cache line size, so always use a power-of-two value. Increase it to the next step up from the default: 64, then 128, then 256 if needed. For most overflow situations, this is sufficient:

http {
    server_names_hash_bucket_size 64;
    ...
}

If the value of 64 still fails, double it again to 128. The goal is the smallest value that allows the hash to build, since the bucket is allocated for every entry.

4. Raise the max size if needed. When you run many virtual hosts or long alias lists and the error references server_names_hash_max_size, increase that directive instead of (or in addition to) the bucket size. The value should be larger than your total number of server names:

http {
    server_names_hash_max_size 1024;
    ...
}

5. Validate the configuration. Always test before reloading so a bad value does not take the service down:

sudo nginx -t

6. Apply the change. Once the test reports syntax is ok and test is successful, reload NGINX gracefully so existing connections are not dropped:

sudo nginx -t && sudo systemctl reload nginx

After the reload, re-run the curl -I and ss -ltnp diagnostics above to confirm the server blocks now respond as expected.

Prevention and Best Practices

A few habits keep this error from recurring:

  • Set sensible defaults proactively. On hosts that serve many domains, define server_names_hash_bucket_size 64; and server_names_hash_max_size 1024; from the start so new sites have headroom.
  • Use power-of-two bucket sizes. Only 32, 64, 128, and 256 are valid because the value must align to the CPU cache line. A non-power-of-two will itself cause a startup error.
  • Increase incrementally. Do not jump straight to 512. Larger buckets waste memory across every server name. Step up one level at a time.
  • Keep server_name lists tidy. Consolidate aliases, prefer wildcard subdomains where appropriate, and remove dead hostnames so the hash stays small.
  • Validate before every reload. Make nginx -t a mandatory step in your deploy pipeline so configuration errors never reach production.
  • Centralize tuning. Put hash directives in the main http block rather than scattering them across included files, so the effective value is easy to audit.

For more configuration tuning guides, browse the NGINX category on DevOps AI ToolKit.

These errors share the same hash-tuning root cause or appear alongside it:

  • could not build map_hash, you should increase map_hash_bucket_size — the same problem in a map block, fixed with map_hash_bucket_size and map_hash_max_size.
  • could not build optimal types_hash, you should increase either types_hash_max_size: 1024 or types_hash_bucket_size: 64 — a non-fatal warning for the MIME types hash, tuned with the corresponding types_hash_* directives.
  • [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use) — an unrelated startup failure, often seen when a previous NGINX process is still bound after a failed reload.
  • directive "server_names_hash_bucket_size" must be a power of two — caused by setting a non-power-of-two value while fixing this error.

Frequently Asked Questions

Does increasing server_names_hash_bucket_size hurt performance or memory? The impact is negligible for most deployments. The bucket size is allocated per hash entry, so very large values across thousands of server names use more memory, but stepping from 32 to 64 or 128 is harmless. Hash lookups remain O(1), so request matching speed does not change.

What is the difference between server_names_hash_bucket_size and server_names_hash_max_size? Bucket size controls how large each individual slot is, which matters when a single server_name is long. Max size controls how many slots the table can hold, which matters when you have a large number of names. The error message tells you which one to raise.

Why does the error show a number like 32 at the end? That number is the current bucket size in bytes that NGINX tried and failed with. It is the limit you exceeded, not the recommended new value. Increase to the next power of two (64, then 128) and re-test with nginx -t.

Where exactly should I put these directives? Both directives belong in the http context of /etc/nginx/nginx.conf, outside any server block. Placing them inside a server or location block produces a separate “directive is not allowed here” error. If you need help triaging recurring config failures, the incident response dashboard can walk you through diagnostics.

Free download · 368-page PDF

Download the Free 500-Prompt DevOps AI Toolkit

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.