How to Fix “server directive is not allowed here” Error in Nginx Configuration


16 views

When working with Nginx, it's crucial to understand where directives can be placed. The error message indicates you're trying to use a server block in an invalid context. The main issue stems from incorrect file inclusion placement.

# Incorrect structure (causes the error)
http {
    # main http context configuration
}
include v.hosts/*.conf;  # This is OUTSIDE the http block

The problem occurs because the include statement is placed outside the http block in your nginx.conf. Server directives can only exist within either:

  • The http context
  • The mail context
  • The stream context

Here's how your nginx.conf should be structured:

user nginx;
worker_processes auto;

error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    access_log    /var/log/nginx/access.log  main;
    charset       utf-8;
    keepalive_timeout 65;
    server_tokens off;
    tcp_nopush    on;
    tcp_nodelay   off;

    # Default server block
    server {
        listen 80;
        server_name _;
        root /usr/share/nginx/html;
        index index.html index.htm;
    }

    # Include virtual hosts
    include /etc/nginx/v.hosts/*.conf;
}

When setting up virtual hosts in separate files:

  1. Ensure all server blocks are within the http context
  2. Use absolute paths for include statements
  3. Keep your main nginx.conf clean and minimal

Example virtual host file (/etc/nginx/v.hosts/example.com.conf):

server {
    listen 80;
    server_name example.com www.example.com;

    access_log /var/log/nginx/example.com.access.log;
    error_log /var/log/nginx/example.com.error.log;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

Always test your configuration before applying changes:

sudo nginx -t
sudo systemctl reload nginx

If you still encounter issues, check the full configuration with:

nginx -T
  • Missing semicolons at the end of directives
  • Unclosed braces (use an editor with syntax highlighting)
  • Incorrect file permissions (config files should be readable by nginx process)
  • Conflicting server_name declarations

When working with Nginx as a reverse proxy, the placement of server blocks is crucial. The error occurs because the include statement appears outside the http block in your nginx.conf:

http {
    # ... existing configuration ...
}

include v.hosts/*.conf;  # This is the problematic line

Nginx configuration has strict structural requirements. The server directive can only exist within specific contexts:

  • Inside http blocks for regular web server configuration
  • Inside stream blocks for TCP/UDP proxying
  • Inside mail blocks for mail proxy configuration

Here's the proper way to structure your main nginx.conf file:

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    access_log    /var/log/nginx/access.log main;
    charset       utf-8;
    keepalive_timeout 65;
    server_tokens off;
    tcp_nopush    on;
    tcp_nodelay   off;

    # Default server
    server {
        listen 80;
        server_name _;
        root /usr/share/nginx/html;
        index index.html index.htm;
    }

    # Include virtual hosts
    include /etc/nginx/v.hosts/*.conf;
}

After making changes, always test your configuration:

sudo nginx -t
sudo systemctl restart nginx

For complex setups, you might need to organize includes differently. Here's an enterprise-level example:

http {
    # Base configurations
    include conf.d/base.conf;
    
    # Virtual hosts
    include sites-enabled/*.conf;
    
    # Custom modules
    include modules/*.conf;
}

# TCP/UDP configurations (separate context)
stream {
    include stream-conf.d/*.conf;
}