Wordpress / PHP – Error Logs and Common Errors + .htaccess replacement
Last updated on June 30th, 2023
https://wpengine.com/support-tag/troubleshooting
Error logs are necessary for most WordPress troubleshooting. You can access the most recent 24 hours of PHP error logs in two different ways: The WP Engine User Portal and the WP Engine WordPress plugin.
NOTE
Looking for Nginx access logs? See our Access Log guide here.
Contents hide
2 Error Log Entries and Severity
[3.1 WPE Monitoring] function.curl_exec [3.3 error] KILLED QUERY [3.4 error] LONG QUERY [3.10 WPE Monitoring] function.session_startAccessing Error Logs
There are two ways to locate and view your website’s error logs, the WP Engine User Portal and through your WordPress admin dashboard.
The best method to access the error logs for your environment is within your WP Engine User Portal. This is because the logs can be easily searched, filtered, and downloaded without needing access to the website’s backend.
- Log in to the User Portal
- Select and environment name
- In the secondary menu, click Logs
- At the top, select Error
Error Log Filters
Severity:
- Need Attention: Items will qualify if their status is 301 or 401.
Time:
This is how far back you can filter the logs to show:
- Last 5 minutes
- Last 30 minutes
- Last 4 hours
Log Details
- Sitename: The selected environment (PROD/STAGING/DEV)
- Site URL: Site url (The selected domain)
- Log type: Error
- Severity: Does this need attention? For example, Needs attention
- Time: The time it was logged
- Status Code: The status code value
- Client: The IP address
- Message: The contents of the error that has occurred on your site.
WordPress Admin Dashboard
Log in to your WordPress dashboard (wp-admin)
Click on the WP Engine tab in the main menu to access our plugin
Select Information
Scroll down to Access and Error Logs
Click the link for the desired log:
- Current error logs refers to the site where you are currently logged in
You can copy and save the unique URLs from here so you can access it at any time from any browser in the event your blog is unavailable.
You can copy and save the unique URLs from here so you can access it at any time from any browser in the event your website is unavailable.
Error Log Entries and Severity
The WP Engine error logs provide you with a trace of how different areas of your site’s code interacts with itself, our server, and WordPress core.
NOTE
This section has technical information geared more towards developers. Plugins and themes do have the ability to add their own logs here as well, so if you see a log not identified here please consult your developer or your plugin/theme author.
Log Name | Summary | Severity |
---|---|---|
PHP Fatal Error | An unrecoverable critical function error. Execution terminated. | High |
Killed Query | Query terminated because it is over 16,000 characters. | High |
WordPress Database Error | Long or numerous MySQL queries being executed. | High |
curl_exec | External API call that takes more than 500ms. | Medium |
File Permissions | PHP Warning showing file permissions that are incorrect. | Medium |
Long Query | Query terminated because it is over over 1,024 characters. | Medium |
PHP Parsing Error | Code is incorrect and could not be ran. Function never executed. | Medium |
PHP Warning | A recoverable critical function error. Executed, not terminated. | Medium |
session_start | Session that is started new or resumed. | Medium |
NGINX Profile Added | Caching exemption added and not an error. | Low |
PHP Notice | Non-critical error caused by undefined variable or index. | Low |
Error Log Examples
We’ve provided some of the more common error long entries below and an brief explanation as to what causes them.
[WPE Monitoring] function.curl_exec Permission denied [error] KILL QUERY [error] LONG QUERY Nginx Profile Added PHP Fatal error PHP Notice PHP Parsing Error PHP Warning [WPE Monitoring] function.session_start WordPress Database Error Internal Recursion Error Enumerate Users
[WPE Monitoring] function.curl_exec
Default PHP Function we’ve added to the error log to show which external API calls are exceeding 500ms; which will add to the total load time of a site and slow it down. This log is intended only for the WP Engine platform to read and is not intended for humans to read. We use this log to help monitor, evaluate, and optimize sites on our platform.
[Mon Jul 14 02:57:21 2014] [error] [client 127.0.0.1] [WPE Monitoring] Stopwatch php.pod-1007.function.curl_exec.duration exceeded 500ms. Was: 1241ms
File Permissions
A permissions error in the error log is a PHP warning. You’ll see this error if a file is trying to be called and the permissions are incorrect. For example, if you uploaded content via SFTP and never reset file permissions via your wp-admin dashboard — both the permissions and the owner/group will be incorrect which will lead to the permission error. You’ll also want to check to ensure the file getting the error actually exists.
PHP Warning: file_put_contents(/nas/wp/www/cluster-1234/yourblog/wp-content/themes/badperms/lib/css/theme.css) [function.file-put-contents]: failed to open stream: Permission denied in /nas/wp/www/cluster-1242/yourblog/wp-content/themes/WFTDAtv/lib/less/lessc.inc.php on line 1418...
[Sat Oct 20 22:38:24 2012] [error] [client 127.0.0.1] PHP Warning: file_put_contents(/nas/wp/www/cluster-1374/yourblog/wp-content/themes/yoo_phoenix_wp/cache/xml-80a72b04a693554d055946d5ad954588.php) [function.file-put-contents]: failed to open stream: Permission denied in /nas/wp/www/cluster-1374/yourblog/wp-content/themes/yoo_phoenix_wp/warp/helpers/xml.php on line 37, referer: http://yourblog.wpengine.com/wp-admin/customize.php
You could also see an error like this if a plugin or theme is trying to do something that’s not allowed on our platform or is trying to access a file/directory it shouldn’t have access to:
PHP Warning: file_put_contents(/nas/wp/www/cluster-2349/yourblog/wp-content/cache/autoptimize/autoptimize_b1b3a88cd5d8cfd4d1b5a716beef375a.php) [function.file-put-contents]: failed to open stream: Permission denied in /nas/wp/www/common/production/php_prevent_flock.php on line 21...
[error] KILLED QUERY
Used to determine which queries of SELECT Statements have been killed and not executed by WP Engine due to the query length being over 16k characters; which is inefficient and should not be ran on a production database.
[Wed Mar 26 06:26:19 2014] [error] [client 127.0.0.1] KILLED QUERY: SELECT DISTINCT `user`.`ID` AS user_id, t.* FROM …
These only apply to Select statements, and not any other type of statements. If these queries need to be run, they should be done so on a local copy of the database that can be downloaded from any backup point in the User Portal. This can be resource intensive; which is why we’ve provided this log. Otherwise, simply shorten the query to resolve the error.
[error] LONG QUERY
Used to determine which queries of SELECT Statements could be optimized due to the character limit being over 1,024.
[Wed Mar 26 06:26:19 2014] [error] [client 127.0.0.1] LONG QUERY: SELECT DISTINCT `user`.`ID` AS user_id, t.* FROM
We have included it in the log to signify that the length of the query, which would be over 1,024 characters, is a Long Query and may be able to be optimized. We did not take any action on this query, it is just a notice to our customers. These only apply to Select statements, and not any other type of statements.
Nginx Profile Added
WPE API [success]: woocommerce Nginx Profile Added – This is not truly an error. With WooCommerce, there are certain caching exemptions that need to be put in place in order for it to function properly. This entry is stating that the nginx profile that contains the necessary cache exemptions has been successfully added to the environment, meaning that the cart and account functions will work as they should.
[Wed Mar 26 06:26:19 2014] [error] [client 127.0.0.1] WPE API [success]: woocommerce Nginx Profile Added
PHP Fatal Error
This is a critical error that can’t be recovered from, such as calling a function that doesn’t exist or there’s not enough memory that’s able to be allocated to the script. If you see a fatal error, it means that the execution of the script was terminated. You can see from the error what plugin/theme/script is causing the issue and in most cases you should be contacting the developer first. PHP fatal errors almost always come from incorrect code.
Function:
PHP Fatal error: Call to undefined function get_current_screen() in /nas/wp/www/cluster-1234/yourblog/wp-content/plugins/leads/modules/wpl.m.post-type.wp-lead.php on line 191, referer: http://yourblog.wpengine.com/wp-admin/
Script:
PHP Fatal error: main() [function.main]: The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "RealScoutColorScheme" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition in /nas/wp/www/cluster-1234/yourblog/wp-content/themes/navigator/style.php on line 18, referer: http://yourblog.com/wp-admin/...
Memory:
PHP Fatal error: Allowed memory size of 536870912 bytes exhausted (tried to allocate 3232498752423 bytes) in /nas/wp/www/cluster-1234/yourblog/wp-includes/taxonomy.php on line 3314, referer:...
Depending on the type of fatal error, a common troubleshooting for memory fatal errors is increasing the memory allocated to PHP. This doesn’t always do the trick, wso contacting your developer is always recommended.
PHP Notice
The script encountered something that could indicate an error, but could also happen in the normal course of running a script. It’s a non-critical error usually caused by an undefined variable or index, so the script is still doing something wrong but the error isn’t serious enough to cause the script to be terminated completely. These errors should still be addressed as they may be indicative of a bug causing problems elsewhere or in the future.
The best course of action is to contact your developer or if it’s specific to a theme/plugin, contact the corresponding author.
PHP Notice: session_start() [function.session-start]: ps_files_cleanup_dir: opendir(/var/lib/php5) failed: Permission denied (13) in /nas/wp/www/cluster-1234/yourblog/wp-includes/plugin.php on line 470...
PHP Notice: wp_specialchars is deprecated since version 2.8! Use esc_html() instead. in /nas/wp/www/cluster-1234/yourblog/wp-includes/functions.php on line 2908...
PHP Parsing Error
Similar to a fatal error, the biggest difference is a parse error will occur before the script is executed. What this means is that syntax of the code is incorrect and it’s not able to be compiled. This will point to an issue with the code itself. It could be a missing character or an unexpected (unneeded) character/symbol that’s causing it, but you’ll be able to tell exactly which line on which file is troublesome from the output of the error. This will usually be a job for your developer or the author of the identified theme/plugin.
PHP Parse error: syntax error, unexpected ')' in /nas/wp/www/cluster-1234/yourblog/wp-content/themes/badtheme/functions.php on line 18
PHP Warning
Similar to a PHP Fatal Error in that the Warning shows a script that is malfunctioning, but PHP was able to recover from and the script was not terminated. Not as serious as a fatal error, but these errors still need to be addressed because they could lead to more serious issues in the future. Just like the fatal error, you’ll want to contact the theme or plugin developer.
PHP Warning: DOMDocument::loadHTML() [domdocument.loadhtml]: error parsing attribute name in Entity, line: 1 in /nas/wp/www/cluster-1234/yourblog/wp-content/plugins/conversations/class/frontend-form-post.php on line 296, referer: http://yourblog.wpengine.com/page/breaking-stuff/...
PHP Warning: fclose() expects parameter 1 to be resource, boolean given in /nas/wp/www/cluster-1234/yourblog/wp-content/plugins/hyper-cache/cache.php on line 253, referer: http://warningsandstuff.com/...
PHP Warning: include() [function.include]: Failed opening '/nas/wp/www/cluster-1234/yourblog/wp-content/advanced-cache.php' for inclusion (include_path='.:/usr/share/php:/usr/share/pear') in /nas/wp/www/cluster-1234/yourblog/wp-settings.php on line 65...
In the above case there’s nothing to fear. It’s just due to the WordPress core trying to get that advanced cache file, but it’s not included with our installations due to our own proprietary caching mechanisms. This specific error can be ignored, or you can add a blank file called advanced-cache.php
to the wp-content
directory.
[WPE Monitoring] function.session_start
Default PHP Function we’ve added to the error log to determine when sessions are resumed or opened; which is identified by either a GET
, POST
, or cookie
.
Session data is saved in a serialized format which PHP retrieves and unserializes in order to populate $_SESSION
.
This log is intended only for the WP Engine platform to read and is not intended for humans to read. We use this log to help monitor, evaluate, and optimize sites hosted with us
[Mon Jul 14 20:11:29 2014] [error] [client 127.0.0.1] [WPE Monitoring] Stopwatch php.pod-1007.function.session_start.duration exceeded 200ms. Was: 749ms
WordPress Database Error
You’ll see database errors when MySQL is overloaded. Typically, this is due to too many queries being run by multiple users or too many long queries being run at one time. In a case like this, the error message will point you to the offending plugin/theme/script. Once the offending theme//plugin is located, ensure that the plugin or theme is completely up to date. If updating doesn’t resolve the issue, you’ll want to contact the developer to see about ensuring that queries run less frequently and are optimized. Sometimes enabling object caching can help as well, as hopefully the queries could then be cached.
[Sun Jun 23 00:01:04 2013] [error] [client 127.0.0.1] WordPress database error Lost connection to MySQL server during query for query...
[Sun Jun 23 00:01:04 2013] [error] [client 127.0.0.1] WordPress database error MySQL server has gone away for query SELECT t.*, tt.* FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON tt.term_id = t.term_id INNER JOIN wp_term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ('post_tag') AND tr.object_id IN (789) ORDER BY t.name ASC /* From [www.yourblog.com/2011/01/22/this-page-breaks-the-database/] in [/nas/wp/www/cluster-1234/yourblog/wp-content/plugins/seo-image/seo-friendly images.php:174] */ made by require('wp-blog-header.php'), require_once('wp-includes/template-loader.php'), include('/themes/freshlife/single.php'), the_content, apply_filters('the_content'), call_user_func_array, seo_friendly_images, preg_replace_callback, seo_friendly_images_process, get_the_tags, get_the_terms, wp_get_object_terms
WordPress database error You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') LIMIT 0, 5 /* From [yourblog.com/?s=crossknowledge] in [/nas/wp/www/cluster-' at line 1 for query SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND (((wp_posts.post_title LIKE '%'))) AND (wp_posts.post_password = '') AND wp_posts.post_type IN ('post', 'page') AND (wp_posts.post_status = 'publish') ORDER BY FIELD(wp_posts.ID, ) LIMIT 0, 5 /* From [yourblog.com/?s=crossknowledge] in [/nas/wp/www/cluster-1234/yourblog/index.php:17] */ made by require('wp-blog-header.php'), wp, WP->main, WP->query_posts, WP_Query->query, WP_Query->get_posts, referer:...
You can also get a database error if the syntax of a query is bad. Like trying to query a table that doesn’t exist as in the error above. When that happens, you will want to get in contact with your developer or the developer of the plugin/theme (if the error is specific to a plugin or theme) to ensure that the queries being generated have good syntax.
Internal Recursion Error
Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.
This error often means there is a 500 error occurring somewhere on the site. If you’re using a multisite, ensure the asset in question actually exists, as this may also reflect a 404.
User Enumeration
Preventing possible attempt to enumerate users
In short, this is not an error but a sign that our firewall is functioning.
The long explanation is that occasionally “bad” bots scrape post information for author ID info and we are automatically preemptively blocking the request. The requests that are blocked when this error displays are not typically not targeted, but rather a wide sweep of WordPress sites probing for vulnerabilities. For example "GET /?author=4 HTTP/1.0" 403
Security Auditor
WP Engine applies an MU plugin to each WordPress website on our platform that specifically logs security events in your wp-admin dashboard. Although these items are logged in your error log, they are not errors and only reflect that a change has been made to your WordPress website. For more information on the Security Auditor see our guide.
These log entries will include the text auditor:event
the followed by one of the following actions:
activated_plugin
deactivated_plugin
switch_theme
upgrader_process_complete
add_user_role
remove_user_role
set_user_role
granted_super_admin
revoked_super_admin
wp_login
user_register
profile_update
deleted_user
retrieve_password_key
updated_option
added_option
deleted_option
users_can_register
default_role
siteurl
home
Platform Settings
Last updated on October 13th, 2023
mediaphpPlatform InformationWordPress
This page offers answers to common questions about default platform settings, WordPress settings, and server configuration settings. You can use this as a quick reference for many settings and how they are configured or changed.
Contents hide
WordPress Memory Limit
The default WordPress Memory Limit is 40MB for a single site, or 64MB for a Multisite network.
These values can be increased to a maximum of 512MB by inserting the following lines under the “WP Engine Settings” section in your wp-config.php file:
define( 'WP_MEMORY_LIMIT', '512M' );
If you want to define a separate higher or lower memory for the WordPress admin area of the site, can add the following line after the one above:
define( 'WP_MAX_MEMORY_LIMIT', '512M' );
WooCommerce recommends setting this value to at least 128MB. You are free to define whichever memory value works best for your site, as long as it does not exceed 512MB.
To make this edit you’ll need access to the file system of your website. Learn more about connecting to your website with SFTP, or the more advanced SSH gateway.
Maximum File Upload Size
The default maximum upload file size for sites is 50MB (or 1MB for multisite networks). You can check what the site is currently registering for the max file upload size from the /wp-admin/upload.php
page:
To increase max file upload size up to a maximum of 256MB please contact Support. Any files larger than 256MB must be uploaded via SFTP or SSH Gateway.
Max File Upload Size on Multisite
In addition to reaching out to Support, you will also need to update the network upload size if you are using a WordPress multisite.
Login to your WordPress admin dashboard
Click My Sites
Select Network Admin
Click Settings
Locate
Max upload file size
- ** The size here is in KB, not MB
PHP Image Resize Limit
WP Engine limits the size of images that can resized using PHP. This size limit is 8000px by 8000px, or 40MP. We’ve put this limit in place to protect server memory and stability, and therefore it cannot be increased.
Plugins that resize images using PHP, such as Smush or ImageMagick, may run into errors if the image is too large. For example you may see the error, width or height exceeds limit
. If you are seeing such an error, resize the image below the limitations prior to attempting the upload again.
PHP Execution Restricted
WP Engine servers block the execution of .php
files from within the wp-content/uploads/
directory. This directory is intended only for media, it is best practice to not execute PHP from these folders.
Post Revisions
WordPress Post Revisions, or autosaves, store a record of each saved draft or published update for a post. This system allows a user to see the last few changes and to restore a page or post to a previous version. While great in theory, revisions cause the database to grow exponentially and a large database can directly impact site performance.
Every WP Engine site has WordPress revisions *disabled* by default. If you need a more extensive revision management system, we recommend using a third-party editing system rather than relying on WordPress revisions.
Revisions can **only** be enabled by contacting Support. Revisions cannot be enabled in the wp-config.php
or php.ini
files, as this will be overwritten at the server level.
If you migrated a site with existing revisions that you would like to preserve, reach out to Support to have revisions enabled.
- Support can help you enable 3 revisions for your posts to start. Revisions should not exceed 5.
- Old revisions will be automatically removed after 60 days.
NOTE
Enabling revisions is not a retroactive change. Only revisions generated after the feature has been enabled will be stored moving forward.
If you would like to clean up your database and delete any existing database revisions, the following query can be run from phpMyAdmin.
DELETE FROM wp_posts WHERE post_type = “revision”;
Sending Email
WP Engine allows general WordPress emails such as password resets to be sent through WordPress below a certain reasonable quantity. However, for sending a large number of emails, such as a newsletter or email blast, we impose a limit and require the use of an email API or an SMTP plugin.
As Port 25 is blocked for all services, we highly recommend using an email service that sends email via API, or an alternative port (such as port 2525).
More information about WP Engine’s email policy can be found here.
TLS Version
All WP Engine servers have TLS 1.2 and 1.3 enabled by default.
TLS 1.0 and 1.1 will be deprecated on March 31st. As TLS 1.0/1.1 deprecation is happening across the industry, we will not be offering the option for customers to defer or opt into a version lower than TLS 1.2. For a majority of customers, an update to TLS 1.2+ should not cause any noticeable impact.
Check out our guide for more information about TLS and SSL.
GZIP and Brotli Compression
WP Engine automatically uses GZIP or Brotli compression to optimize performance of static files (like images, text files, JavaScript, and CSS) on your web server. As a result, GZIP and Brotli directives should not need to be added separately.
If the browser requesting the file supports Brotli compression, the file will be served compressed with Brotli. If the requesting browser does not support Brotli the file will be served compressed with GZIP.
The following file types are automatically compressed by WP Engine with Brotli:
text/plain
text/css
application/javascript
application/x-javascript
text/xml
application/x-font-opentype
application/x-font-truetype
application/x-font-ttf
application/xml
application/xml+rss
font/eot
font/opentype
text/javascript
image/x-icon
image/bmp
image/svg+xml
The following file types are automatically compressed by WP Engine with GZIP:
application/rss+xml
application/vnd.ms-fontobject
application/wasm
application/x-javascript
application/x-web-app-manifest+json
application/xhtml+xml
application/xml
application/xml+rss
font/otf
image/bmp
image/svg+xml
image/x-icon
text/cache-manifest
text/calendar
text/css
text/javascript
text/log
text/markdown
text/plain
text/richtext
text/vcard
text/vnd.rim.location.xloc
text/vtt
text/x-component
text/x-cross-domain-policy
text/xml
text/xsd
text/xsl
Max Execution Time
Default max_execution_time
for scripts is set to 60 seconds.
This setting can only be decreased, and cannot be increased. If you are performing a task which will take over 60 seconds to complete, the task should be broken into smaller segments and run in batches.
Max Input Vars
The default max_input_vars
setting is 10000, indicating no more than 10,000 variables can be attached to any request.
This setting cannot be adjusted, as this is set at a platform level and higher values will have negative performance implications.
NOTE
WP Engine does not support .htaccess. Review our guide for alternatives.
Security Headers
If you want to ensure extra security on your site through the use of headers, many are already added by default. If the header you’d like is not enabled automatically, they can be added through the Web Rules page in your User Portal.
CORS
Cross-Origin Resource Sharing headers are defined by default for all static resources on sites (images, styles, JavaScript, etc). You can see this by curling for the headers on a static file. For example:
HSTS
HTTP Strict Transport Security (HSTS) is a security policy allowing web servers to declare that browsers (or other complying user agents) should only interact using secure HTTPS connections. Setting this up on WP Engine can be done by adding a header to the Web Rules area of the User Portal.
This rule is the simplest HSTS header that can be added, indicating that once a browser has read the header it should remember it for 63072000 seconds (2 years).
add_header Strict-Transport-Security "max-age=63072000";
When added as a header rule it will look like the following:
Optional directives:
HSTS headers come with two additional directives: preload
and includeSubdomains
. Adding both of these additional directives would look like this:
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
Below are all the default directives you will typically need to pass a security header test. These headers can be modified as-needed.
A few notes about the directives:
The
includeSubdomains
affects all subdomains, even ones on other hosts. This is due to the browser registering the HSTS header with the directive and will apply it to all relevant subdomainsThe
preload
directive allows a site to be to be registered at
, which adds the domain to the Chrome HSTS preload list that is hard coded in to browsers. Other browsers also use this list.
- If there is an error with the verification on this service, make sure that no domain-level redirects are set in the User Portal. For example, non-www to www or vice versa. Any redirects from the root domain must be removed completely.
- Removal from the
preload
list can be a lengthy process:Be aware that inclusion in the preload list cannot easily be undone. Domains can be removed, but it takes months for a change to reach users with a Chrome update and we cannot make guarantees about other browsers.
Misc Security Headers
The following security headers can also be added through the Web Rules page of the User Portal. We’ve included examples of the most common header options, but many can be modified to suit your specific needs.
Vary
Ensures the correct content is delivered for the specific browser. This is particularly relevant when caching or proxy layers are at play, as older browsers may not understand more modern compression or file types. The following is the recommended rule configuration.
proxy_set_header Vary "Accept-Encoding";
X-XSS Protection
Protects (typically older) browsers from cross-site scripting attacks. The following is the recommended configuration rule.
add_header X-XSS-Protection "1; mode=block";
Feature Policy
Allows opt-in and opt-out standardization for features on a website, particularly when APIs or third-party apps are used. The following is a usable example but it can be modified if necessary.
add_header Feature-Policy "geolocation 'none';midi 'none';notifications 'none';push 'none';sync-xhr 'none';microphone 'none';camera 'none';magnetometer 'none';gyroscope 'none';speaker 'self';vibrate 'none';fullscreen 'self';payment 'none';";
Referrer-Policy
Identifies the address of the webpage associated with a requested resource. The following is a usable example but can be modified for different needs.
add_header Referrer-Policy "origin" always;
X-Content-Type-Options
Allows deliberate setting of MIME types by forcing requests to follow and not change the set content-type
. Learn more about this header on Mozilla.
add_header X-Content-Type-Options "nosniff" always;
X-Frame-Options
Determines whether or not a page can be loaded as a <frame>
, <iframe>
, <embed>
or <object>
. The following tells the page that it can only be displayed as one of these types on a page with the same origin. This rule can be modified to allow other URIs if needed.
add_header X-Frame-Options "SAMEORIGIN" always;
Server Modules
WP Engine has a specific set of platform-wide server modules which cannot be modified, removed, or added. To see a full list of modules, versions, and default settings, you can create a PHP Info file.
Disabled Functions and Modules
Our system administrators have already pre-configured server settings to best suit the needs of the majority of our clients. Some functions cannot be modified from site to site or in the php.ini file as they are configured at a server level.
Here are some functions that have been disabled and therefore are not able to be altered:
- apache_child_terminate
- apache_get_modules
- apache_get_version
- apache_getenv
- apache_note
- apache_setenv
- disk_free_space
- disk_total_space
- diskfreespace
- dl
- exec
- passthru
- pclose
- pcntl_exec
- popen
- posix_getpwuid
- posix_kill
- posix_mkfifo
- posix_setpgid
- posix_setsid
- posix_setuid
- posix_uname
- proc_close
- proc_get_status
- proc_nice
- proc_open
- proc_terminate
- shell_exec
- show_source
- system
- opcache_get_configuration
- opcache_get_status
- auto_prepend_file
Miscellaneous Modules
Module | Is it installed? |
---|---|
ionCube Loader | No |
cURL support | Yes |
SOAP client | Yes |
Imagick | Yes |
Disallowed Plugins
Most plugins are allowed on the WP Engine platform, however a handful of plugins we specifically disallow, as they will cause issues with either security or performance.
View our current list of disallowed plugins.
Although they are not disallowed, some plugins are still incompatible with the WP Engine platform. This is most impactful for plugins and themes utilizing ionCube. The ionCube Loader module is not available on WP Engine due to the significant performance issues it causes.
Learn more about unsupported modules.
PHP Version
PHP Versions are regularly released and deprecated. To see which versions are currently available on the WP Engine farm and how to change versions, check out our PHP Upgrade Guide.
MySQL Version
WP Engine uses MySQL 5.7 but will be upgrading to MySQL 8 by October 2023.
Learn more about this upgrade, and how to find a site’s current MySQL version here.
Configuration Files
There are several site and server-wide configuration files in place for each environment. Some files are accessible and able to be modified, while others are not.
Configuration file | Is it editable? |
---|---|
php.ini file | No. Server-wide PHP settings are unable to be changed. |
.htaccess file | No. WP Engine has deprecated the .htaccess file. |
wp-config.php file | Yes. This file can be edited, but there are many WP Engine-specific settings in this file which should not be changed. For the best results, put custom entries in the “WP Engine Settings” section at the bottom. |
nginx.conf file | No. Server or site-specific Nginx settings are not able to be adjusted. If there is a specific Nginx setting you wish to adjust, please contact Support to see if there are any internal changes which may be made |
WP Engine MU Plugins
There are certain must-use plugins that you may see added to your WordPress website by WP Engine. These are added for specific reasons, such as security or functionality.
While we don’t recommend it, some of these plugins can be disabled. If you’d like to remove a WP Engine MU plugin, reach out to our Support team.
WP Engine Common
The wpengine-common
plugin provides most of the WP Engine platform functionality. Platform features provided by this plugin can be seen in your wp-admin dashboard under the WP Engine menu icon.
This plugin provides access to platform functionality, such as post-processing and cache adjustments. It can be accessed at /admin.php?page=wpengine-common
This plugin cannot be disabled, however the menu icon can be hidden with custom coding.
WP Engine Seamless Login
The wpe-wp-sign-on-plugin
plugin files are added for the WP Engine “Seamless Login” feature. This feature gives you the ability to securely log in to the wp-admin of a website directly from the User Portal.
To learn more about this functionality see the Seamless Login guide.
WP Engine Security Auditor
The wpengine-security-auditor
plugin performs two main functions:
- Log security-relevant events to the Site Error Log. Examples of logged events are login, role changes, and plugin upgrades.
- Periodically calculate and log checksums for plugins, themes, and WP core files.
For a full list of these items as they display in your logs, see our guide.
We do not recommend disabling this plugin as it adds security features. However, if you find too many events are being logged it can be disabled by adding the following feature flag to your wp-config.php
file:
define('WPENGINE_SECURITY_AUDITOR_ENABLED', false);
Force Strong Passwords
The plugin force-strong-passwords
is added to force all users with access to the wp-admin are of your site to use strong passwords. Strong passwords are only required for Administrator, Editor, and Author roles. It is not required for “weaker” roles like Subscriber and Contributor. Our system to force a strong password only requires users to set a strong password when resetting the password from the wp-login.php page.
This plugin should never be disabled as it can create a serious security vulnerability in your website.
To learn more about forcing strong passwords, see our full guide.
NEXT STEP: Learn more about .htaccess alternatives
Wordpress setting that replace .htaccess settings
Default WordPress .htaccess Directives
By our analysis, most WP Engine websites will not need to make any changes as they are using a default WordPress version of the .htaccess. Default WordPress rewrites will be handled by WP Engine automatically at the server level.
If your .htaccess file contains only default content, no changes need to be made. You can find the default .htaccess files used for WordPress here.
If your .htaccess file contains content beyond the default WordPress state, see the alternatives below.
Directive Alternatives Overview
If your site is using .htaccess directives outside of the default WordPress rules (above), we have put together a list of recommended alternatives.
Directive | Purpose | Alternative |
---|---|---|
Deny from all | Restrict access | By default, PHP files have guards at a platform level that prevent them from being served. Other static files are served by Nginx and not Apache.Nginx rules can be added to replicate this behavior if needed by contacting Support. |
Allow from all | Allow access | PHP files have guards at a platform level that prevent them from being served. Other static files are served by Nginx and not Apache.Nginx rules can be added to replicate this behavior if needed by contacting Support. |
Rewrites | Forces redirects and rewrites | Add 301 and 302 redirects to the User Portal. User Portal redirects are better for performance and scaleability.Contact Support with custom Nginx rewrites, if needed.Use a plugin.Read more about migrating redirects. |
SetHandler | Specifies how to handle certain file types | NoneStatic assets are served by Nginx and not Apache (where the .htaccess would be processed). |
Option-indexIgnore* | Prevent directory browsing | NoneWP Engine already disallows indexing of directories by default. |
mod_ Headers | Header tweaking | Headers should be sent with PHP code. |
AddType | Adds MIME type support for app type | Static assets are served by Nginx and not Apache (where the .htaccess would be processed).If additional rules are desired, they can be added to the Nginx config by contacting Support. |
Caching | Sets cache expirations | WP Engine manages caching rules at a server level for you, by default.Additional caching rules can be managed in PHP code.Extra caching rules for static assets can be applied to Nginx by contacting Support. |
Security | Disable PHP processing (Ex: Akismet and Gravity Forms) | WordPress plugins often add security rules to the .htaccess. WP Engine already applies these rules by default at a server level.Plugins should handle additional directives in their PHP code. |
Access Rules
Managing access rules can be done from your User Portal as an alternative to placing these rules in the .htaccess. All websites on WP Engine automatically have this Web Rules page enabled. Learn more about managing web rules here.
Below are examples of how to translate the following .htaccess directives into Access Rules.
rewrite_deny
- Rewrite with status code 403 by creating a DENY access web rule.
satisfy
- This directive is only used when a particular area of your site is restricted by a combination of client IP address and user/password authentication.
- Password protection for WordPress paths can be done via plugins instead.
- Protection for all paths (served by NGINX) is not yet supported.
Redirects and Rewrites
If your site had redirect rules in the .htaccess, they should be relocated in order to remain both functional and optimized. It is always recommended to consolidate as many rules as possible using RegEx regardless of the number of redirects needed or how they are applied.
Fewer Than 1000 Redirects
Redirects can be added to WP Engine’s Nginx configuration
- Add redirects through the User Portal
- Bulk import redirects by contacting WP Engine Support
Add redirects rules to the Redirection plugin
Manage redirects in Yoast SEO Premium‘s redirect manager
More Than 1000 Redirects
- Importing redirects into the WP Engine Nginx configuration will not be efficient at this quantity, due to bloating and overhead.
- We suggest loading redirects into the Redirection plugin or, if you’re using Yoast SEO, manage redirects in Yoast Premium
Bulk Migrate Redirects from the .htaccess
All of the recommended redirect alternatives allow the bulk import of Apache (.htaccess-formatted) redirects. This means importing existing redirects from the .htaccess can be done quickly and easily, and does not require redirects be moved one at a time. Simply copy the rules from your .htaccess file, then import using the guide:
- Bulk import redirects to the WP Engine Nginx configuration
- Bulk import redirects to Redirection plugin
- Bulk import redirects to Yoast Premium redirect manager
Rewrite Rules
Redirects and rewrites can be added to your WP Engine configuration using either Redirect Rules or Rewrite Rules. Below are examples of alternatives when using the Web Rules Rewrite Rules.
redirect
- https://httpd.apache.org/docs/2.4/mod/mod_alias.html#redirectmatch
- Can be added as a Redirect Rule or a Rewrite Rule
rewritebase_not_root
https://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritebase
The
Web Rules Engine
does not have the concept of a document root, so you’ll need to add the new “base” in the destination RegEx URL. For example:
- Action: internal
- Source: ^/index.html
- Destination: /myapp/welcome.html
rewrite_arbitrary_status
- Not Supported.
rewrite_cond_existing
https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewritecond
In the .htaccess this may appear as:
- RewriteEngine On
- RewriteCond %{HTTP_USER_AGENT} “=ROBOT-UA” [OR]
- RewriteCond %{HTTP_USER_AGENT} “=EVIL-ROBOT-UA”
- RewriteRule “^/index.html$” “bot.html”
Note the presence of the
[OR]
. Web Rule Conditionals are AND’ed together, so in order to replicate this you will need to duplicate the rule 2 times, each with the respective condition. Converted to a Rewrite Rule this may look like the following example:
Rule 1:
Action: internal
Source: ^/index.html
Destination: bot.html
Conditions:
- Type: Header
- Operator: Equals (=)
- Name: User-Agent
- Value: ROBOT-UA
Rule 2:
Action: internal
Source: ^/index.html
Destination: bot.html
Conditions:
- Type: Header
- Operator: Equals (=)
- Name: User-Agent
- Value: EVIL-ROBOT-UA
rewrite_cond_notexisting
- https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewritecond
- ENV, REMOTE_ADDR, HTTPS, REQUEST_SCHEME, etc.
- Not supported.
rewrite_missing
- Not Supported.
rewrite_not_index
Converted to a Rewrite Rule this may look like the following example:
- Action: internal
- Source: ^/index.php
- Destination: /blah.php
rewrite_redirect
https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewriterule
This rule the RewriteRule directive to perform a 3xx redirect. In the .htaccess it may appear as:
- RewriteRule (.*) https://www.example.com/$1 [R=301,L]
The presence of the
L
flag in this case means this should be the
first
rewrite rule if there are
multiple
rewrite rules. As a
Rewrite Rule
this may appear as:
- Action: permanent
- Source: (.*)
- Destination: https://www.example.com/$1
WordPress Features
Below are examples of how to translate the following .htaccess directives using WordPress features.
browsermatch
- https://httpd.apache.org/docs/current/mod/mod_setenvif.html#browsermatch
- Implement a check in PHP around the User-Agent Header ($_SERVER[‘HTTP_USER_AGENT’]) and set an env if it matches.
env
- Can access through $_ENV
php_flag
/
php_value
- Certain php config values can be changed at runtime using the ini_set() function. Reference: https://www.php.net/manual/en/configuration.changes.modes.php
requestheader
- https://httpd.apache.org/docs/current/mod/mod_headers.html#requestheader
- Instead, use the WordPress send_headers hook.
- Get and modify request headers with PHP ($_SERVER[‘HTTP_MY_HEADER’])
setenv
- https://httpd.apache.org/docs/2.4/mod/mod_env.html#setenv
- Can be done in wp-config.php using define or through $_ENV
WP Engine Platform Features
Below are examples of how to translate the following .htaccess directives into existing WP Engine Platform features.
errordocument
require
https://httpd.apache.org/docs/2.4/mod/mod_authz_core.html#require
This is used for access control, typically for
basic authentication
, when combined with .htaccess directives like:
- AuthType Basic
- AuthName “Restricted Area”
- AuthUserFile /path/to/.htpasswd
- Require valid-user
The Password Protection Feature can be used when controlling access to the entire site.
The below .htaccess rule is similar to a
Deny All
rule, which could be created in the
Web Rules Engine
instead.
Require all denied
Typically used in conjunction with:
- <IfModule mod_authz_core.c>
- Require all denied
In an .htaccess file in a directory like /wp-content/uploads/dlm_uploads/.htaccess to deny all access to that directory.
Password protecting specific directories or URLs is not supported.
The wpe-wp-sign-on-plugin
plugin files are added for the WP Engine “Seamless Login” feature. This feature gives you the ability to securely log in to the wp-admin of a website directly from the User Portal.
To learn more about this functionality see the Seamless Login guide.
WP Engine Security Auditor
The wpengine-security-auditor
plugin performs two main functions:
- Log security-relevant events to the Site Error Log. Examples of logged events are login, role changes, and plugin upgrades.
- Periodically calculate and log checksums for plugins, themes, and WP core files.
For a full list of these items as they display in your logs, see our guide.
We do not recommend disabling this plugin as it adds security features. However, if you find too many events are being logged it can be disabled by adding the following feature flag to your wp-config.php
file:
define('WPENGINE_SECURITY_AUDITOR_ENABLED', false);
Force Strong Passwords
The plugin force-strong-passwords
is added to force all users with access to the wp-admin are of your site to use strong passwords. Strong passwords are only required for Administrator, Editor, and Author roles. It is not required for “weaker” roles like Subscriber and Contributor. Our system to force a strong password only requires users to set a strong password when resetting the password from the wp-login.php page.
This plugin should never be disabled as it can create a serious security vulnerability in your website.
To learn more about forcing strong passwords, see our full guide.