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


2 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;
}