Web

WordPress Init Hook Not Triggering: Fixes & Troubleshooting

Troubleshoot why WordPress init hook not triggering in custom plugins. Common causes like activation timing, conflicts, and errors. Step-by-step fixes, debug logs, best practices, and working code examples for reliable init hook firing.

1 answer 1 view

Why the init Hook Might Not Fire

Common Cause Why It Happens Quick Fix
Plugin file not loaded The file isn’t in the wp-content/plugins folder or the folder name is wrong. Verify the folder name and file path.
Plugin header missing or malformed WordPress can’t recognize the file as a plugin. Ensure the header block is at the very top and correctly formatted.
Hook added before WordPress core loads If the hook is added too early (e.g., in a file that’s included before wp-load.php), it won’t register. Keep the add_action() call in the main plugin file, not in an included file that runs before WordPress loads.
Hook name typo A misspelled hook name means WordPress never calls it. Double‑check the hook name (init).
Function defined after the hook call PHP allows this, but if the file is parsed in a different order (e.g., via require_once), the function may not exist yet. Define the function before the add_action() call or use add_action() inside a function that runs after the function is defined.
Plugin deactivated or not activated The plugin isn’t active, so its code never runs. Go to Plugins → Installed Plugins and confirm it’s activated.
init hook suppressed by another plugin/theme Rare, but a plugin or theme could remove the hook or replace it. Disable other plugins/themes to isolate the issue.
Error in the plugin file A fatal error stops execution before the hook is added. Check wp-content/debug.log or enable WP_DEBUG to see errors.
Wrong PHP version or syntax error Syntax errors prevent the file from loading. Validate the PHP file with a linter.

Typical Troubleshooting Steps

  1. Enable Debugging
php
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );

Then check wp-content/debug.log for any errors.

  1. Verify Plugin Activation
    Go to Plugins → Installed Plugins and confirm the plugin is active.

  2. Check File Location
    The file should be directly inside a folder in wp-content/plugins.
    Example: wp-content/plugins/test-init-hook/test-init-hook.php.

  3. Confirm Header Block

php
<?php
/*
Plugin Name: Test Init Hook Plugin
Description: A simple plugin to test the init hook.
Version: 1.0
Author: Your Name
*/
  1. Move Hook Registration Inside a Function
php
<?php
/*
Plugin Name: Test Init Hook Plugin
*/

function test_init_hook_register() {
add_action( 'init', 'my_custom_init_function' );
}
add_action( 'plugins_loaded', 'test_init_hook_register' );

function my_custom_init_function() {
error_log( 'Init hook triggered' );
}

Using plugins_loaded ensures the hook is added after all plugins are loaded.

  1. Check for Conflicting Hooks
    Temporarily disable other plugins and switch to a default theme (e.g., Twenty Twenty‑Three). If the hook fires, the conflict is with another plugin/theme.

  2. Look for remove_action Calls
    Search the codebase for remove_action( 'init', ... ). If found, it may be removing your hook.

  3. Confirm PHP Error Reporting
    Add ini_set( 'display_errors', 1 ); at the top of the plugin file to see any runtime errors.

Minimal Working Example

php
<?php
/*
Plugin Name: Test Init Hook Plugin
Description: Demonstrates a working init hook.
Version: 1.0
Author: Your Name
*/

add_action( 'init', 'my_custom_init_function' );

function my_custom_init_function() {
 error_log( 'Init hook triggered' );
}

Place this file in its own folder inside wp-content/plugins, activate it, and then check wp-content/debug.log. You should see the log entry after any page load.

Summary

  • Ensure the plugin file is correctly located and activated.
  • Verify the header block and hook name.
  • Define the function before adding the hook or wrap the registration in a plugins_loaded callback.
  • Enable debugging to catch any hidden errors.
  • Disable other plugins/themes to rule out conflicts.

Once these steps are followed, the init hook should fire and the log message will appear.

If your WordPress init hook not triggering in a custom plugin, it’s usually not the code—it’s WordPress’s activation process or a sneaky loading issue. During plugin activation, WP scans headers but skips full execution of your add_action('init', ...) until the next page load. Refresh the frontend, check debug logs, and wrap registrations in plugins_loaded for reliability.


Contents


Understanding the WordPress Init Hook and When It Fires

The init hook is a core part of WordPress’s loading sequence. It fires after the basics load—think core files, database connection, and constants—but before headers send or queries kick off. Perfect for grabbing $_GET or $_POST data, loading text domains, or setting up rewrites.

But here’s the catch: it doesn’t fire everywhere. Skip the admin AJAX requests or cron jobs sometimes, and it’s silent. According to the official WordPress documentation, init comes right after wp_loaded in the grand scheme? No—actually before wp_loaded, which waits for everything else. Confusing? Yeah, but knowing this stops half the headaches.

Your plugin code registers fine with add_action('init', 'my_custom_init_function'), assuming the function exists. Still not seeing it? Timing during activation is culprit number one.


Why the Init Hook Doesn’t Trigger During Plugin Activation

Plugin activation trips everyone up. WordPress hits plugins.php, reads your header to list it, but doesn’t run your full plugin file yet. By the time init fires on that request, your code hasn’t loaded.

Picture this sequence from Stack Exchange discussions:

  1. WP loads plugins.php.
  2. Scans all plugin dirs for headers.
  3. init hook triggers—your new plugin? Not included yet.
  4. Activation happens, but your add_action registers too late for this cycle.

Result? No log, no output on activation screen. Reload any frontend page, and boom—it works. Another thread confirms: post-activation loads behave normally. Test there first. Ever refreshed and forgotten? Happens daily.


Common Reasons the Init Hook Fails in Custom Plugins

Beyond activation, plenty derails init hook not firing in plugins. Here’s a breakdown:

Common Cause Why It Happens Quick Fix
Plugin file not loaded Wrong folder or path in wp-content/plugins. Double-check wp-content/plugins/your-plugin/your-plugin.php.
Plugin header missing/malformed WP ignores the file entirely. Top of file: /* Plugin Name: ... */ exact format.
Hook added too early Before wp-load.php in includes. Keep add_action in main file.
Typo in hook name 'initt' or 'Init'—case-sensitive. Verify 'init'.
Function defined after hook PHP parses late if order flips. Define function first.
Plugin not activated Duh, but easy miss. Plugins screen → Activate.
Suppressed by conflicts Another plugin removes it. Disable all but yours.
Fatal errors Syntax halts everything. Enable debug log.
PHP version mismatch Old syntax on new PHP. Linter check.

Tom McFarlin nails it: no “perfect” init spot—too early for screen functions. Multisite? Extra layer of pain.


Step-by-Step Troubleshooting for Init Hook Not Triggering

Ready to diagnose WordPress init hook not triggering? Follow this checklist—no guesswork.

  1. Confirm basics: Folder structure right? wp-content/plugins/test-plugin/test-plugin.php. Header perfect? Activate it fresh.

  2. Test post-activation: Never trust the activation page. Visit homepage, admin dashboard. Reload.

  3. Isolate conflicts: Switch to Twenty Twenty-Four theme. Deactivate other plugins. Works? Hunt the culprit.

  4. Wrap in safer hook: Ditch direct init reg. Use this:

php
function register_my_hooks() {
add_action('init', 'my_custom_init_function');
}
add_action('plugins_loaded', 'register_my_hooks');
  1. Search for removals: Grep codebase: remove_action('init'. Rare, but kills it.

  2. Admin vs. frontend: init fires everywhere, but test both. Admin-only logic? Switch contexts.

Stack Exchange unpacks activation flow—your code loads post-scan. Brutal, but true.

Stuck? Logs next.


Verifying Execution: Error Logs and Debug Techniques

Nothing beats logs for init hook not firing plugin mysteries. Flip these in wp-config.php:

php
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);

Hit a page. Check wp-content/debug.log for “Init hook triggered” or errors. No entry? Hook never registered.

Quick hacks:

  • Temp wp_die('Init fired!'); in your function—page crashes if it runs.
  • error_log('Checkpoint: add_action called'); before hook.
  • ini_set('display_errors', 1); error_reporting(E_ALL); top of plugin.

General hook tips from SE stress load order. PHP linter? php -l your-plugin.php. Clean? Good.

What if silent? Permissions on debug.log—chmod 666.


Best Practices and Alternatives to the Init Hook

Don’t fight init forever. Guard duplicates:

php
if (did_action('init') === 0) {
 add_action('init', 'my_function');
}

Alternatives shine brighter. Codex on activation—use for setup, not ongoing. Prefer:

  • plugins_loaded: All plugins ready.
  • wp_loaded: Queries done, screens available.
  • Priorities: add_action('init', 'func', 20);.

Tuts+ covers pitfalls—early hooks tempt, later deliver. Multisite? muplugins_loaded first.

Pro tip: Conditional tags inside function. if (is_admin()) saves cycles.


Complete Fixed Code Example and Testing Checklist

Here’s battle-tested code. Drop in wp-content/plugins/test-init/test-init.php:

php
<?php
/*
Plugin Name: Test Init Hook Plugin
Description: Reliable init hook test.
Version: 1.0
Author: You
*/

if (!defined('ABSPATH')) {
 exit;
}

function register_init_hooks() {
 add_action('init', 'my_custom_init_function');
}
add_action('plugins_loaded', 'register_init_hooks');

function my_custom_init_function() {
 error_log('Init hook triggered at ' . current_time('mysql'));
 // Your real code here
}

Testing checklist:

  • [ ] Folder: wp-content/plugins/test-init/test-init.php
  • [ ] Activate → Visit site → Check debug.log
  • [ ] Conflicts? Default theme, solo plugin.
  • [ ] Errors? Linter + WP_DEBUG.
  • [ ] Multisite? Network activate.

Fires every load. Scale from here.


Sources

  1. Init Hook — Official documentation on timing and usage: https://developer.wordpress.org/reference/hooks/init/
  2. Add_action init not executed before activation — Explains plugin activation sequence limitations: https://wordpress.stackexchange.com/questions/237467/in-a-plugin-why-is-add-actioninit-not-executed-before-the-plugin-is-activat
  3. Why init hook doesn’t work — Details post-activation hook behavior: https://stackoverflow.com/questions/50786450/why-init-hook-doesnt-work
  4. Initialize WordPress Plugins — Best practices for hook selection and pitfalls: https://tommcfarlin.com/initialize-wordpress-plugins/
  5. Question on init and activation hooks — Breakdown of WP plugin loading order: https://wordpress.stackexchange.com/questions/363591/a-question-on-init-and-activation-hooks
  6. Hooks are not executing — Troubleshooting general hook failures: https://wordpress.stackexchange.com/questions/85485/hooks-are-not-executing
  7. WordPress Initialization Hooks — Common mistakes and lifecycle overview: https://code.tutsplus.com/articles/wordpress-initialization-hooks-benefits-and-common-mistakes--wp-34427
  8. register_activation_hook — Limits on activation hook registration: https://developer.wordpress.org/reference/functions/register_activation_hook/

Conclusion

WordPress init hook not triggering boils down to activation quirks, conflicts, or early calls—your syntax is rarely the villain. Prioritize post-activation tests, plugins_loaded wrappers, and debug logs to nail it every time. Grab that fixed example, enable logging, and you’re live. Questions? Tweak and log more—WP reveals all eventually.

Authors
Verified by moderation
WordPress Init Hook Not Triggering: Fixes & Troubleshooting