Operations 8 min read

Why Did Nginx Return 403? Uncovering Permissions, UMASK, and Jenkins Pitfalls

This article walks through a real‑world deployment failure where Nginx returned 403 errors, explains Linux file permission bits, the impact of UMASK on generated files, and how Jenkins and Tomcat settings caused the issue, offering step‑by‑step troubleshooting and resolution.

Efficient Ops
Efficient Ops
Efficient Ops
Why Did Nginx Return 403? Uncovering Permissions, UMASK, and Jenkins Pitfalls

Background

The release system consists of Jenkins invoking a deployment program (code‑named varian ) that builds a Docker image, pushes it to a registry, and updates a container cluster accessed via a load balancer.

The original varian was a mix of shell and Python scripts with many compatibility hacks, making the codebase messy. A refactor was undertaken to rewrite varian entirely in Python, modularize functionality, and upgrade Jenkins to the latest version with JDK 1.8.

New environment details:

OS: Debian 8

Language: Python 3.4

JDK 1.8 + Jenkins 2.134

Fault Handling Process

Resolving Nginx 403 Errors

After deploying a static HTML project via Jenkins, the web page loaded without styles because the CSS file returned a 403 status. The browser console showed the failed request.

Typical reasons for Nginx returning 403 include:

IP not in whitelist

Directory listing disabled for a directory request

File owned by a user/group without read permission for the Nginx worker user

Incorrect index directive (e.g., pointing to index.shtml when only index.html exists)

In this case the problem was file permissions: Nginx ran as www-data, but the CSS file was owned by root with no permissions for others.

Understanding Linux File Permissions

-rw-r----- 1 root root 7.9K Jul 24 12:34 csl.css

The first ten characters represent the permission bits. The first character indicates the file type ( - for regular file, d for directory, l for link). The next nine characters are grouped in threes for owner, group, and others, with r =4, w =2, x =1.

Owner has read/write (rw‑)

Group has read only (r‑‑)

Others have no permissions (---)

Other fields show link count, owner, group, size, modification time, and filename.

Tomcat8 UMASK Issue

Running the deployment script directly from a Linux console produced files with correct permissions, but the same script executed by Jenkins resulted in incorrect permissions.

Investigation revealed that the generated files inherited the UMASK value of the process. Both the root and Jenkins users had a UMASK of 0022, which should yield 644 for files. However, Tomcat8 (the container running Jenkins) changed its default UMASK to 0027, causing the generated CSS file to lack read permission for the Nginx user.

After adjusting Tomcat8’s UMASK back to 0022, the permission problem was resolved.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

troubleshootingJenkinsfile-permissionsumask403
Efficient Ops
Written by

Efficient Ops

This public account is maintained by Xiaotianguo and friends, regularly publishing widely-read original technical articles. We focus on operations transformation and accompany you throughout your operations career, growing together happily.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.