This check flags Azure Storage accounts where queue service logging is turned off, leaving you blind to who read, wrote, or deleted queue messages. Without it you have no audit trail for incident response. Fix it by enabling read, write, and delete logging through a Storage Analytics or diagnostic settings configuration.
Azure Queue Storage is one of those services that quietly underpins a lot of asynchronous workloads. Order processing, background jobs, event fan-out, decoupling between microservices. Because it sits in the middle of so many pipelines, the messages flowing through it are often sensitive: customer identifiers, internal commands, payment references, and more. The trouble is that by default, Azure does not record who touches those queues. If logging is disabled and something goes wrong, you are left guessing.
The Storage Account Queue Service Logging Disabled check (storage_queuenologging) catches exactly this gap. It looks at each Storage account and verifies that queue service logging is enabled for read, write, and delete operations.
What this check detects
Azure Storage offers a feature historically called Storage Analytics logging (the classic $logs mechanism) and a newer equivalent through Azure Monitor diagnostic settings. Both can capture detailed records of requests made against the queue service endpoint of a Storage account.
This check fails when a Storage account has no queue service logging configured, meaning none of the following operation categories are being recorded:
- Read requests, such as peeking or dequeuing messages
- Write requests, such as enqueuing new messages or creating queues
- Delete requests, such as removing messages or deleting queues
Note: Queue logging is configured independently of blob, table, and file logging. An account can have rich blob logging and still have queue logging completely disabled, which is exactly the situation this check is designed to surface.
Why it matters
Logging is one of those controls that feels optional until the day you desperately need it. Here is what you lose without queue service logging.
No forensic trail during an incident
Suppose an attacker gains a shared access signature (SAS) token or a leaked account key. They start dequeuing messages from a queue that drives your payment reconciliation jobs. With logging disabled, there is no record of the source IP, the authentication mechanism used, or the timing of those requests. You cannot reconstruct what was accessed, which turns a contained incident into an open-ended investigation.
Compliance gaps
Frameworks like PCI DSS, SOC 2, ISO 27001, and HIPAA all expect audit logging on systems that process regulated data. If queues carry cardholder data or protected health information, missing logs can directly fail an audit and stall a certification.
Warning: Diagnostic logs and Storage Analytics logs are written into your own storage, which means they consume capacity and incur transaction and storage costs. High-throughput queues can generate a large volume of log data, so pair logging with a retention policy to keep the bill predictable.
Operational blind spots
Beyond security, logs help you debug. A poison message that keeps getting picked up and never deleted, an unexpected spike in dequeue failures, a client that is hammering the queue with throttled requests. All of these are far easier to diagnose when you have request-level logs to inspect.
How to fix it
You have two supported approaches. The modern path uses Azure Monitor diagnostic settings, which is what Microsoft recommends going forward. The classic path uses Storage Analytics logging, which is still common in older estates.
Option 1: Diagnostic settings (recommended)
Diagnostic settings route queue logs to a Log Analytics workspace, a storage account, or an Event Hub. Here is how to enable read, write, and delete logging to a Log Analytics workspace using the Azure CLI.
az monitor diagnostic-settings create \
--name queue-logging \
--resource "/subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.Storage/storageAccounts/<account>/queueServices/default" \
--workspace "/subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.OperationalInsights/workspaces/<workspace>" \
--logs '[
{"category": "StorageRead", "enabled": true},
{"category": "StorageWrite", "enabled": true},
{"category": "StorageDelete", "enabled": true}
]'
Note the resource path points at the queueServices/default sub-resource, not the storage account itself. This is a common mistake that results in the setting being applied to the wrong scope.
Option 2: Storage Analytics logging (classic)
If your tooling or compliance baseline still relies on the $logs container, you can enable classic logging like this.
az storage logging update \
--account-name <account> \
--account-key <key> \
--services q \
--log rwd \
--retention 90
The --services q flag targets the queue service, --log rwd enables read, write, and delete, and --retention 90 keeps logs for 90 days.
Console steps
- Open the Azure Portal and navigate to your Storage account.
- Under Monitoring, select Diagnostic settings.
- Choose the queue resource from the list.
- Click Add diagnostic setting.
- Check StorageRead, StorageWrite, and StorageDelete.
- Select a destination (Log Analytics workspace is the most useful for querying), then Save.
Tip: Sending logs to a Log Analytics workspace instead of a storage container lets you query them with KQL and build alerts. For example, you can alert on a burst of anonymous queue reads, which is far harder to do when logs are sitting as flat files in a container.
Terraform example
If you manage infrastructure as code, bake the diagnostic setting into your module so logging is never an afterthought.
resource "azurerm_monitor_diagnostic_setting" "queue_logging" {
name = "queue-logging"
target_resource_id = "${azurerm_storage_account.this.id}/queueServices/default"
log_analytics_workspace_id = azurerm_log_analytics_workspace.this.id
enabled_log {
category = "StorageRead"
}
enabled_log {
category = "StorageWrite"
}
enabled_log {
category = "StorageDelete"
}
}
Danger: If you are switching a production account from classic Storage Analytics logging to diagnostic settings, do not delete the old $logs container until you have confirmed the new pipeline is capturing data and your downstream queries or SIEM ingestion have been repointed. Removing the old logs prematurely creates a coverage gap.
How to prevent it from happening again
Fixing one account is easy. Keeping every account compliant as your estate grows is the real challenge. Lean on policy and automation.
Azure Policy
Azure ships with built-in policy definitions that audit or deploy diagnostic settings for Storage accounts. Assign a DeployIfNotExists policy so that any new Storage account automatically receives queue logging configuration.
az policy assignment create \
--name "deploy-queue-diagnostics" \
--policy "<deployifnotexists-policy-definition-id>" \
--scope "/subscriptions/<sub-id>" \
--location eastus \
--mi-system-assigned \
--role "Contributor"
With a DeployIfNotExists assignment, a remediation task can backfill logging on accounts that predate the policy, so you do not have to chase them down manually.
CI/CD gates
Catch the misconfiguration before it ever reaches Azure. Run a policy-as-code scan against your Terraform plan or Bicep templates in the pipeline and fail the build if queue diagnostic settings are missing.
# Example: scan Terraform with a policy engine in CI
checkov -d ./infra --check CKV_AZURE_* --compact
# Or run Lensix against deployed resources on a schedule
# and surface storage_queuenologging failures in your dashboard
Tip: Combine a preventive CI gate with a runtime scanner like Lensix. The CI gate stops new drift, and the runtime scan catches changes made directly in the portal or by automation that bypassed your pipeline.
Best practices
- Enable logging for all four services consistently. Do not stop at queues. Apply the same read, write, and delete logging to blob, table, and file services so your audit posture is uniform.
- Centralize logs in Log Analytics. A workspace gives you KQL querying, retention controls, and alerting in one place, which beats scattered
$logscontainers across dozens of accounts. - Set a retention period that matches your compliance window. Many frameworks expect at least 90 days of readily accessible logs and a year or more in cold storage. Configure retention deliberately rather than leaving the default.
- Alert on anomalies, not just collect logs. Logs you never look at have limited value. Build alerts for anonymous access, unexpected source IPs, and unusual deletion spikes.
- Prefer managed identities and Entra ID auth over account keys. When requests are authenticated with identities, your logs become far more meaningful because they tie actions to a principal rather than an opaque shared key.
Queue logging is a small configuration change with an outsized impact on your ability to investigate and prove what happened. Turn it on everywhere, enforce it with policy, and verify it continuously. The cost is modest, and the day you need those logs you will be glad they exist.

