Fix Nginx "Could Not Build server_names_hash" for Django Sites

Fix the Nginx emerg error could not build server_names_hash, you should increase server_names_hash_bucket_size when adding long domain names or many Django sites: set the bucket and max size in the http block, test, and reload safely.

Problem statement

You add a new site, a longer subdomain, or a batch of tenant domains, and Nginx refuses to load the configuration:

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

or the related form:

nginx: [emerg] could not build server_names_hash, you should increase
either server_names_hash_max_size: 512 or server_names_hash_bucket_size: 64

Nginx stores every server_name in a hash table for fast lookup. The bucket size limits how long a single name may be, and the max size limits the table as a whole. A long name like staging-api.eu-west.customer-portal.example.com, or hundreds of names for multi-tenant Django, exceeds the defaults. The fix is two lines in the http block.

Why Nginx refuses to startAdd server_namelong or manyNginx builds hashat config loadBucket too smalldefault 32 or 64emerg errorconfig rejectedLong or numerous server names need a larger hash bucket or table.
  1. Open /etc/nginx/nginx.conf.
  2. Inside the http { } block, set server_names_hash_bucket_size 128; (on Debian and Ubuntu, uncomment the existing line and change it).
  3. If the message mentions max size too, add server_names_hash_max_size 1024; (or larger for many names).
  4. Test with sudo nginx -t.
  5. Reload with sudo systemctl reload nginx.

Step-by-step solution

1. Edit the http block

Debian and Ubuntu ship this commented out in nginx.conf:

http {
    # server_names_hash_bucket_size 64;
    # server_name_in_redirect off;
    ...
}

Uncomment and raise it:

http {
    server_names_hash_bucket_size 128;
    server_names_hash_max_size 1024;
    ...
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

The directives are only valid in the http context. Putting them inside a server block gives a different emerg error: "server_names_hash_bucket_size" directive is not allowed here.

in the http block of nginx.confhttp {server_names_hash_bucket_size128;server_names_hash_max_size1024;include/etc/nginx/sites-enabled/*;}1231Room for long names; use a power of two.2Room for many names; raise for multi-tenant sites.3Must come after the hash settings in the same block.Both settings belong in http, never in a server blockdjango-deployment.com
If the error persists, double each value and test again.

2. Test before reloading

sudo nginx -t

syntax is ok and test is successful mean you can reload safely. A reload keeps the old workers serving until the new configuration is active, so a failed test never takes the site down; a failed restart would.

3. Size it for many tenant domains

If each Django tenant has its own domain listed in server_name, the table grows with every customer. Increase server_names_hash_max_size in powers of two (2048, 4096) as needed. For hundreds or thousands of domains, consider a catch-all server and let Django route by host instead:

server {
    listen 443 ssl default_server;
    server_name _;
    # certificates issued on demand by a proxy such as Caddy, or a wildcard
    location / { proxy_pass http://app; proxy_set_header Host $host; }
}

Then Django's ALLOWED_HOSTS and tenant lookup decide which domains are valid.

4. Reload and verify

sudo systemctl reload nginx
curl -sI https://staging-api.eu-west.customer-portal.example.com | head -1
edit, test, reload1Open nginx.confthe http block2Raise bucket size64 to 1283Raise max size if asked512 to 1024 or more4Run nginx -tmust pass5Reload, not restartno downtimeA reload keeps serving with the old config if anything is wrongdjango-deployment.com
Always test first; the error stops a restart but not a running server.

Explanation

Nginx matches the request's Host header against server_name values using hash tables built at startup. Each bucket must fit at least one name plus overhead, and its default size matches the CPU cache line (32, 64, or 128 bytes depending on the processor). A name longer than roughly the bucket size cannot be stored, and too many names cannot be spread over the table without exceeding server_names_hash_max_size. Raising the limits costs a small amount of memory and nothing measurable in speed.

Edge cases / notes

  • Wildcard and regex names. *.example.com and regex names are stored differently, but exact names still need to fit the hash.
  • Config management. Ansible roles and Docker images often provide their own nginx.conf; set the value there, or it will be overwritten.
  • Containers. The official Nginx image reads /etc/nginx/nginx.conf; mount a custom one or use a conf.d include placed inside the http block.

Next steps

FAQ

What value should server_names_hash_bucket_size have?

128 handles almost any realistic domain name. Use powers of two.

Does a larger bucket slow Nginx down?

No measurable effect for typical sites. It uses slightly more memory.

Why did adding one subdomain break Nginx?

The new name was longer than the default bucket can hold. Length, not count, triggers the bucket-size form of the error.

Can I put the setting in my site file?

Only if that file is included inside the http block outside any server block. Most site files contain only a server block, so put it in nginx.conf.

Keep going