Permalink repair guide

The default WordPress .htaccess file, explained.

Broken post URLs, unexpected 404s, or a missing rewrite block usually point here. The current rules are printed in full below — copy them, and restore them without overwriting the configuration that is actually yours.

01WordPress owns one block.

Core writes the lines between # BEGIN WordPress and # END WordPress.

02It belongs at the install root.

For a normal site, that is the directory containing wp-config.php, not the theme or uploads folder.

03Preserve your additions.

Keep host, cache, HTTPS, or security directives outside WordPress’s managed markers.

What the default block does

On Apache, a pretty permalink such as /about/ is not a physical file. The standard WordPress rewrite block lets real files and directories continue normally, then sends the remaining requests to index.php. WordPress reads the requested path and chooses the post, page, archive, or 404 response.

That is why the rules are relevant when the home page works but posts return 404 errors after a migration, a file restore, or a permalink change. They do not apply to Nginx, and they cannot make rewrites work when Apache’s mod_rewrite module or the relevant AllowOverride setting is unavailable.

1 Visitor requests a permalink2 Apache checks for a real file3 Rewrite sends the rest to index.php4 WordPress selects the content
.htaccess — single site at the domain root
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

That is the entire block for a standard install: no hardening, nothing host-specific. WordPress writes it when you save Settings → Permalinks and rewrites everything between the two markers whenever permalinks change, so any directive of your own has to live outside them.

<IfModule mod_rewrite.c>Runs the block only where Apache's rewrite module exists, so a server without it serves pages instead of a 500 error.
RewriteEngine OnTurns rewriting on for this directory and everything beneath it.
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]Copies the Authorization header into an environment variable PHP can read. It is what keeps application passwords and REST API authentication working on CGI and FastCGI servers, which otherwise drop that header.
RewriteBase /The URL path WordPress is installed at. A subdirectory install needs that path here, not a bare slash.
RewriteRule ^index\.php$ - [L]Leaves a direct request for index.php alone, which is what stops the rules looping back on themselves.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
Rewrite only when the request does not match a real file (-f) or a real directory (-d). This is why images, stylesheets and /wp-admin/ keep loading normally.
RewriteRule . /index.php [L]Everything else goes to index.php, where WordPress reads the requested path and decides which post, page, archive or 404 to return. [L] means stop processing rules here.

Use the rules for your installation, not a random snippet

A single WordPress site installed at the web root uses a different destination from a site installed in a subdirectory such as /blog/. The generator produces the standard block for either case, so you do not need to edit regular expressions by hand.

.htaccess — single site installed in /blog/
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]
</IfModule>
# END WordPress

Two lines carry the installation path — RewriteBase and the final RewriteRule — and the file belongs in the directory WordPress actually lives in, so /blog/.htaccess rather than the document root. The exception is the “give WordPress its own directory” layout, where the site address and the installation directory deliberately differ: there the block stays in the document root with RewriteBase /.

InstallationPut the main block hereImportant detail
Web-root single siteThe document root beside wp-config.php.The rewrite base is normally /.
Subdirectory single siteThe WordPress installation directory.Generate rules with the actual base, such as /blog/.
Multisite networkThe network’s WordPress root.Use the dedicated multisite rules instead; see the multisite guide.

A safe way to restore it

  1. 01
    Confirm that Apache serves the site.

    If the host uses Nginx, LiteSpeed, or a managed proxy, ask where rewrite rules live before creating a file that the server will ignore.

  2. 02
    Save the existing file first.

    Download or copy the current .htaccess. It may contain directives from the host, cache plugin, or a security product that should not disappear.

  3. 03
    Generate only the WordPress block you need.

    Choose “single site” and the correct installation base in the local .htaccess generator.

  4. 04
    Replace the managed markers, not the whole file.

    Update the section between WordPress’s BEGIN and END comments, leaving custom directives outside that section intact.

  5. 05
    Test a post, a page, and the admin.

    Open an ordinary permalink, a static media file, and /wp-admin/. If only permalinks fail, resave Settings → Permalinks after verifying the file is writable.

Quick answers

What is the default WordPress .htaccess file?

It is the Apache rewrite block shown above: it routes pretty permalink requests through index.php while letting real files and directories load unchanged. WordPress writes it between its # BEGIN WordPress and # END WordPress markers when you save Settings then Permalinks.

Should I delete my entire .htaccess file and start again?

No. Back it up first, then replace only the WordPress-managed section unless you have verified that the other directives are obsolete. Hosts and plugins often add rules outside the WordPress markers.

Why does my site still show 404s after restoring the rules?

The server may not permit .htaccess overrides, mod_rewrite may be unavailable, the site may use Nginx, or the WordPress installation base may be wrong. Check those before adding more rules.

Can I add other rules to the same file?

Yes — anything outside WordPress's BEGIN/END markers is untouched by Core. Common additions include blocking PHP execution in wp-content/uploads and a proxy-aware HTTPS redirect (see the redirect loop guide before adding one).

Primary reference: WordPress server configuration documentation.