Ninja Forms Bug During Migration: Discovery and Fix

By: Bobby

Published on: Nov 03, 2025

4 min read.

As a full-stack web developer specializing in WordPress and working on open source technologies, you are going to run into hosting issues from time to time. and troubleshooting. I love sharing real-world fixes to help fellow devs and site owners. Here’s a recent Ninja Forms bug I encountered on MySQL 8.0.31, WordPress 6.8.3, and phpMyAdmin—plus how I solved it.

The Migration Mishap

I migrated a client’s site using All-in-One WP Migration. Post-transfer, Ninja Forms vanished from pages, and the Settings tab triggered a fatal error.

A few weeks ago, I onboarded a new client excited about upgrading their hosting setup. Their site was built on WordPress 6.8.3, running PHP (via phpMyAdmin for database tweaks), and MySQL 8.0.31. They were using Ninja Forms for handling user submissions—think contact forms, registrations, and the like—which is a go-to plugin for its ease of use and flexibility.

To minimize downtime, I opted for the All-in-One WP Migration plugin to transfer the site from their old host to my server. The process went off without a hitch: files copied over, database imported, URLs updated, and the site was live in under an hour. I always do a thorough post-migration walkthrough, clicking through pages, testing forms, and checking core functionality. That’s when I hit the first snag.

The site’s Ninja Forms? Nowhere to be found. The forms that should have been embedded on key pages had vanished. No biggie at first—I figured it was a simple activation hiccup. But when I headed to the WordPress admin dashboard and clicked into Ninja Forms > Settings, boom: a fatal error crashed the page. Time to roll up my sleeves and check the error logs.

Error Logs Reveal Missing Tables

Error logs are like a developer’s diary—they spill the beans on what’s really going on under the hood. I fired up the server logs and spotted a cascade of database-related red flags. Here’s a redacted snippet of what I saw (I’ve blurred out sensitive details like IPs, domains, and paths for privacy):

[Sun Nov 02 22:32:27.886747 2025] [proxy_fcgi:error] [pid 64769] [client [CLIENT_IP]:51322] AH01071: Got error 'ss database error Table '[DB_PREFIX]_nf3_action_meta' doesn't exist for query 
                SELECT `value`
                FROM   `[DB_PREFIX]_nf3_action_meta`
                WHERE  `parent_id` = 0
                AND    `key` = 'email_message_plain'
                 made by set_current_screen, WP_Screen->set_current_screen, do_action('current_screen'), WP_Hook->do_action, WP_Hook->apply_filters, NF_Admin_Menus_Forms->admin_init, Ninja_Forms->activation, NF_Abstracts_ModelFactory->import_form, NF_Database_Models_Form::import, NF_Abstracts_Model->save, NF_Abstracts_Model->_save_settings, NF_Abstracts_Model->_save_setting; PHP message: WordPress database error Table '[DB_PREFIX]_nf3_action_meta' doesn't exist for query SHOW FULL COLUMNS FROM `[DB_PREFIX]_nf3_action_meta` made by set_current_screen, WP_Screen->set_current_screen, do_action('current_screen'), WP_Hook->do_action, WP_Hook->apply_filters, NF_Admin_Menus_Forms->admin_init, Ninja_Forms->activation, NF_Abstracts_ModelFactory->import_form, NF_Database_Models_Form::import, NF_Abstracts_Model->save, NF_Abstracts_Model->_save_settings, NF_Abstracts_Model->_save_setting', referer: https://[DOMAIN]/wp-admin/admin.php?page=nf-submissions
[Sun Nov 02 22:32:29.072253 2025] [proxy_fcgi:error] [pid 63562] [client [CLIENT_IP]:51323] AH01071: Got error 'PHP message: WordPress database error Table '[DB_PREFIX]_nf3_forms' doesn't exist for query SELECT COUNT( `id` ) AS total FROM `[DB_PREFIX]_nf3_forms`; made by do_action('admin_init'), WP_Hook->do_action, WP_Hook->apply_filters, Ninja_Forms->admin_init; PHP message: PHP Warning:  Undefined array key 0 in [SERVER_PATH]/wp-content/plugins/ninja-forms/ninja-forms.php on line 560; PHP message: PHP Warning:  Trying to access array offset on value of type null in [SERVER_PATH]/wp-content/plugins/ninja-forms/ninja-forms.php on line 560; PHP message: WordPress database error Table '[DB_PREFIX]_nf3_forms' doesn't exist for query 
                SELECT `id`, `title`, `created_at`
                FROM `[DB_PREFIX]_nf3_forms`
                ORDER BY `title`
             made by do_action('wp_ajax_nf_forms'), WP_Hook->do_action, WP_Hook->apply_filters, NF_AJAX_REST_Controller->route, NF_AJAX_REST_Forms->get, NF_Database_FormsController->getFormsData, NF_Database_FormsController->setFormsData; PHP message: WordPress database error Table '[DB_PREFIX]_nf3_form_meta' doesn't exist for query SELECT link.parent_id as 'form_id', link.value as 'public_link_key'
            FROM `[DB_PREFIX]_form_meta` as link
            LEFT JOIN `[DB_PREFIX]_form_meta` as allowed
            ON allowed.parent_id = link.parent_id
            WHERE link.key = 'public_link_key'
            AND allowed.key = 'allow_public_link'
            AND allowed.value = '1'; made by do_action('wp_ajax_nf_forms'), WP_Hook->do_action, WP_Hook->apply_filters, NF_AJAX_REST_Controller->route, NF_AJAX_REST_Forms->get, NF_Database_FormsController->getFormsData, NF_Database_FormsController->setFormsData', referer: https://[DOMAIN]/wp-admin/admin.php?page=ninja-forms

phpMyAdmin confirmed: no Ninja Forms tables, despite a full backup.

Database Deep Dive: Confirming the Missing Pieces

Next stop: phpMyAdmin. I logged into the database (a full export from the old host) and ran a quick search. Sure enough, those Ninja Forms tables were absent on the new server, even though the migration should have brought everything over. Odd—All-in-One WP Migration is usually bulletproof for this.

Since I had a complete backup, I decided to surgically reimport just the missing tables. I extracted the relevant SQL from the dump and fired it up. But… import failed. The error message was a head-scratcher at first:

#3750 - Unable to create or change a table without a primary key, when the system variable 'sql_require_primary_key' is set.

MySQL 8+ requires explicit primary keys for better replication performance. Confirmed here: Percona article on sql_require_primary_key.

Original SQL example:

CREATE TABLE `so_nf3_actions` (
  `id` int NOT NULL AUTO_INCREMENT,
  `title` longtext,
  `key` longtext,
  `type` longtext,
  `active` tinyint(1) DEFAULT '1',
  `parent_id` int NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `updated_at` datetime DEFAULT NULL,
  UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ;

The Fix: Add Primary Key

No sweat—this was an easy tweak. I edited the SQL to add PRIMARY KEY (id) right after the column definitions, swapping out the UNIQUE KEY:

CREATE TABLE `so_nf3_actions` (
  `id` int NOT NULL AUTO_INCREMENT,
  `title` longtext,
  `key` longtext,
  `type` longtext,
  `active` tinyint(1) DEFAULT '1',
  `parent_id` int NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `updated_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ;

I applied this pattern to all the missing tables (forms, meta, actions—you get the idea), reimported via phpMyAdmin, and… success! The tables populated without a hitch. Back in WordPress, I reactivated Ninja Forms, refreshed the admin page, and the forms reappeared like magic. A quick test submission confirmed everything was humming along.

Pro tip: If you’re hitting this in your own setup, you could temporarily set SET SESSION sql_require_primary_key = 0; for the import session, but I’d recommend fixing the schema properly to avoid future headaches.

Reporting the Bug

With the site stable, I didn’t stop there. I bundled up the error logs, the SQL example, and a step-by-step reproduction guide, then submitted it via Ninja Forms’ official support portal. Bugs like this are golden for plugin maintainers—they help make the ecosystem stronger. As of now, I’m awaiting their response, but fingers crossed this nudges them toward MySQL 8+ compatibility in future updates.

Wrapping Up: Lessons from the Trenches

Migrations are a staple of web dev life, but they always teach something new. This Ninja Forms hiccup highlighted how version mismatches (MySQL 8’s primary key rule) can sneak up on even battle-tested plugins. If you’re migrating WordPress sites, double-check your database schema against your server’s MySQL version, and keep those error logs handy—they’re your best friend.

Got a similar story or a question about hosting tweaks? Drop a comment below or hit me up—I’m always down to chat tech. Thanks for reading, and happy coding!

— Bobby

Full-Stack Dev | Catchylabs.com

Leave a Reply