AppArmor is blocking an application
A confinement profile is refusing an operation. The denial in the log names the profile, the operation and the path.
What you see
An application fails with permission denied on a file whose Unix permissions are clearly correct. Common with MySQL, nginx and Docker after moving a data directory.
What is actually wrong
The profile permits the default paths only. Moving a data directory, adding a socket, or writing to a new location is denied even when the filesystem permissions allow it.
Codes and articles
Fixes (2)
Confirm AppArmor is the cause
Permission denied that the filesystem does not explain.
Look for denials.
sudo dmesg -T | grep -i apparmor | tail -20sudo journalctl -k --since '30 min ago' | grep -i 'apparmor.*DENIED'
Check which profiles are loaded and in what mode.
sudo aa-status | head -20Put the profile into complain mode temporarily to confirm the diagnosis. It logs what it would have blocked instead of blocking it.
sudo aa-complain /usr/sbin/mysqldComplain mode is the right diagnostic: the application works, and the log fills with exactly the permissions the profile is missing. Disabling AppArmor entirely proves the same thing and leaves the machine unconfined.
Reproduce the failure and read the new log lines.
sudo journalctl -k --since '5 min ago' | grep -i apparmor
Add the specific permission to the profile
You know what is being denied.
Use the local override file so the change survives a package upgrade.
sudo ls /etc/apparmor.d/local/Editing the shipped profile works until the package updates and replaces it. The local directory is included by the main profile precisely so site changes are kept separate.
Add the rule for the new path.
echo '/srv/mysql/** rwk,' | sudo tee -a /etc/apparmor.d/local/usr.sbin.mysqldReload the profile.
sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.mysqldAlternatively, use the interactive tool, which reads the denials and proposes rules.
sudo aa-logprofPut the profile back into enforcing mode and re-test.
sudo aa-enforce /usr/sbin/mysqldsudo aa-status | grep mysqld
sudo aa-status | head -10sudo dmesg -T | grep -ci 'apparmor.*DENIED'
Where this stops. This write-up was written and checked by hand. It says what each step changes, how to confirm it worked and how to reverse it, and anything destructive is flagged before you reach it. If it does not match what your machine is doing, search the Support Centre for the exact code or message — and when something needs a person, get in touch.