{"record":{"id":"f886d9c16a3138bc","repo":"nginx/nginx","slug":"ngx-log-emerg-f886d9","errorCode":"NGX_LOG_EMERG","errorMessage":"invalid variable name \\\"%V\\\"","messagePattern":"invalid variable name \\\\\"%V\\\\\"","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/http/modules/ngx_http_map_module.c","lineNumber":222,"sourceCode":"        return NGX_CONF_ERROR;\n    }\n\n    value = cf->args->elts;\n\n    ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));\n\n    ccv.cf = cf;\n    ccv.value = &value[1];\n    ccv.complex_value = &map->value;\n\n    if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {\n        return NGX_CONF_ERROR;\n    }\n\n    name = value[2];\n\n    if (name.data[0] != '$') {\n        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,\n                           \"invalid variable name \\\"%V\\\"\", &name);\n        return NGX_CONF_ERROR;\n    }\n\n    name.len--;\n    name.data++;\n\n    var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE);\n    if (var == NULL) {\n        return NGX_CONF_ERROR;\n    }\n\n    var->get_handler = ngx_http_map_variable;\n    var->data = (uintptr_t) map;\n\n    pool = ngx_create_pool(NGX_DEFAULT_POOL_SIZE, cf->log);\n    if (pool == NULL) {\n        return NGX_CONF_ERROR;","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/nginx/nginx/blob/3f6f7824d4e2eb1ac37dec76683d525ac0ff521c/src/http/modules/ngx_http_map_module.c#L204-L240","documentation":"Validation in the map directive handler of ngx_http_map_module.c: the third argument to 'map <source> <target> {' must be the target variable name and must start with '$'. After stripping the '$', the name is registered via ngx_http_add_variable(). A missing or malformed leading '$' is rejected with NGX_LOG_EMERG.","triggerScenarios":"A map directive whose second parameter does not begin with '$': 'map $uri /path {...}', 'map $uri path {...}', 'map $uri ${var} {' style typos, or a map line where the target variable was accidentally deleted.","commonSituations":"Writing the target as a plain identifier out of habit from rewrite-map syntaxes of other servers, templating that strips the '$' (e.g. shell or envsubst expanding $newvar inside the config), or copy-paste that drops the variable.","solutions":["Prefix the target variable with '$': map $uri $newvar { ... }","Quote configs processed by envsubst or shell heredocs so '$' is preserved (e.g. use quoted heredoc <<'EOF' or escape \\$)","Check the map directive has exactly two arguments before the block: source and $target","Validate with nginx -t"],"exampleFix":"# before\nmap $uri backend_flag { default 0; }\n# after\nmap $uri $backend_flag { default 0; }","handlingStrategy":"validation","validationCode":"# second map argument must start with '$'\nawk '/^[ \\t]*map[ \\t]/ && /\\{/ { if ($3 !~ /^\\$/) print FILENAME\":\"FNR\": map target must be $var: \"$3 }' /etc/nginx/nginx.conf /etc/nginx/conf.d/*.conf\nnginx -t","typeGuard":null,"tryCatchPattern":"if ! nginx -t 2>err.log; then cat err.log; exit 1; fi","preventionTips":["Both map arguments are variables and start with '$'","Use quoted heredocs or escape \\$ when configs pass through envsubst/shell","Add a pre-commit grep for map lines missing '$'"],"tags":["nginx","map","variables","config"],"backgroundTag":"invalid-variable-name","analyzedSha":"3f6f7824d4e2eb1ac37dec76683d525ac0ff521c","analyzedAt":"2026-08-22T03:09:46.447Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}