Fix Nginx 'could not build the server_names_hash' Error When Configuring Many Virtual Hosts

intermediateโšก Nginx2026-05-08| Nginx 1.14+ on Ubuntu 20.04/22.04, Debian 11/12, CentOS 7/8, any Linux distro

Error Message

fatal: [emerg] could not build the server_names_hash, you should increase server_names_hash_bucket_size: 64
#nginx#server_name#config-error#vhost

What Happened

I was adding a new virtual host to an Nginx server that already had about a dozen domains configured. After running nginx -t to validate the config, I got slapped with this:

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

Nginx refused to reload. The new site stayed dead. The error log offered zero additional context โ€” just that single line. Two lines in nginx.conf fixed it, but figuring out which two lines and why required some digging.

Root Cause

Nginx stores every server_name value in a hash table for fast lookup. Each bucket in that table defaults to 64 bytes. When a domain name โ€” or the collective weight of all your domain names โ€” can't fit into a 64-byte bucket, Nginx fails to build the table on startup and throws this error.

Common triggers:

  • Long domain names like some-very-long-subdomain.client-company-name.example.com (easily 50+ characters)
  • Wildcard entries like *.subdomain.example.com
  • Lots of aliases crammed into a single server_name directive
  • Adding a new vhost that pushed the total hash size over the limit

Debugging Steps

Start by identifying which config is causing the problem:

nginx -T 2>&1 | grep server_name

This dumps the full merged config. Scan for unusually long names or server blocks loaded with aliases. Then run the config test and read the error closely:

sudo nginx -t

If the error says bucket_size: 64, bump it to 128. If it already says bucket_size: 128, double it again to 256.

Want to find your longest server name quickly? Run this:

grep -r 'server_name' /etc/nginx/sites-enabled/ | awk '{print length, $0}' | sort -rn | head -5

A name hitting 60โ€“70 characters is your culprit. Anything under 50 characters usually fits fine at the default 64-byte bucket size.

The Fix

Open /etc/nginx/nginx.conf and add or update the following inside the http block:

http {
    # Increase hash bucket size for long server names
    server_names_hash_bucket_size 128;
    server_names_hash_max_size 512;

    # ... rest of your config
}

These two directives solve different problems:

  • server_names_hash_bucket_size โ€” controls each individual bucket's size. Must be a power of 2: 64 โ†’ 128 โ†’ 256. Raise this when a single domain name is too long to fit.
  • server_names_hash_max_size โ€” controls the total number of buckets. Default is 512. Only matters when you're hosting hundreds of domains โ€” most people never need to touch this.

For the typical server hitting this error, server_names_hash_bucket_size 128 alone is enough. Setting it to 256 upfront costs nothing and buys you headroom for future domains.

Apply the Fix

# Test config first โ€” always
sudo nginx -t

# If test passes, reload
sudo systemctl reload nginx

Verification

A clean test looks like this:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Then confirm the service is up and the new vhost responds:

sudo systemctl status nginx
curl -I http://your-new-domain.com

Debugging remotely or through a load balancer? Check the worker processes directly:

ps aux | grep nginx

You should see one master process and at least one worker. Only a master with no workers means something still failed to load.

Edge Cases

Error Persists After Setting 128

If the error now reads bucket_size: 128, you have a genuinely massive domain name. Jump straight to 256:

server_names_hash_bucket_size 256;

Powers of 2 only. Setting something like 192 won't work โ€” Nginx will either silently round it down or throw a separate error.

Config Is in a Separate Include File

Some distros fragment nginx.conf into multiple includes. Double-check that the directive lands inside the http block, not a server block:

nginx -T 2>&1 | grep -A2 -B2 'server_names_hash'

Drop it inside a server block by accident and the directive is silently ignored โ€” the error keeps coming back and you'll waste an hour wondering why.

Prevention

These days, these two lines go into every fresh Nginx install before any vhosts are even configured:

server_names_hash_bucket_size 128;
server_names_hash_max_size 1024;

Takes 10 seconds. Saves you from a failed reload at 2am when someone adds a domain like staging-api.long-client-name.internal.example.com.

If you manage several Nginx servers and want to validate configs before pushing them, nginx -t -c /path/to/test.conf lets you test a local copy before deploying. For verifying that the config you tested is byte-for-byte what landed on the server, I run a SHA-256 check using the Hash Generator at toolcraft.app โ€” runs in-browser, nothing gets uploaded.

Lessons Learned

  • Always run nginx -t before systemctl reload nginx. A reload with a broken config fails silently โ€” your old config keeps running and you get no warning.
  • The 64-byte default is fine for short names. The moment someone adds a subdomain like portal.north-america-region.client.example.com, you're over the limit. Set 128 from day one.
  • The error message is a bit misleading. It points at bucket_size, but if you're hosting 300+ domains, max_size is what actually needs adjusting. Check both.
  • This error only surfaces at config load time โ€” startup or reload. A server that's been running fine for months can suddenly refuse to reload after a single config change. Nothing broke before; the new name just pushed it over the threshold.

Related Error Notes