Skip to content

Latest commit

 

History

History
251 lines (156 loc) · 11.2 KB

File metadata and controls

251 lines (156 loc) · 11.2 KB

Troubleshooting

Use this guide when a shortcode does not render a usable download link or a protected link stops with an error.

Start Here

Confirm that:

  • the visitor is logged in
  • exactly one download source is configured
  • the user currently qualifies through manage_options, an allowed role, a recorded WooCommerce purchase, or an eligible WooCommerce subscription
  • required plugins are active for the configured access method
  • the page was reloaded after changing settings, purchases, roles, subscriptions, release tags, uploaded assets, or GitHub credentials

Protected links are tied to one user, expire after 15 minutes, and become invalid after a successful redirect or local GitHub ZIP preparation. Reload the page to create a new link when the user still has access.

Invalid Download Source

Invalid download source provided. means the shortcode does not define exactly one valid source.

Check for:

  • no url or github_repo
  • both url and any GitHub source attribute
  • github_tag or github_asset without a valid github_repo
  • a repository value that is not in owner/repository format

Use either:

[file_access url="https://example.com/plugin.zip"]

or:

[file_access github_repo="littlebizzy/private-plugin"]

Invalid File URL

The configured Invalid File URL message is used only when a non-empty url value cannot be accepted as an HTTP or HTTPS destination.

Confirm that the URL:

  • begins with http:// or https://
  • is complete and correctly quoted in the shortcode
  • does not use another protocol such as ftp:, file:, or javascript:

Missing or conflicting source attributes use the separate built-in invalid-source message.

User Does Not Have Access

Access methods use OR logic. A logged-in user needs only one of the following:

  • the manage_options capability
  • an allowed WordPress role
  • a recorded purchase of an allowed WooCommerce product
  • an active or pending-cancel subscription for an allowed subscription product ID

A non-empty shortcode products, roles, or subscriptions value replaces the corresponding saved default for that download. It is not merged with the default.

Access is checked when the shortcode is displayed and checked again when the protected link is opened. Reload the page after changing the user's access.

WooCommerce Purchase Is Not Recognized

Product purchase checks require WooCommerce and use its native purchase history check.

Confirm that:

  • WooCommerce is active
  • the configured product ID is correct
  • WooCommerce considers the order paid
  • the order belongs to the same logged-in WordPress user account

Secure File Access supplies the logged-in user ID and does not match guest purchases by billing email. A guest order or an order attached to another account will not grant access.

Secure File Access does not add separate refund rules, download limits, license keys, or guest-purchase matching.

Subscription Is Not Recognized

Subscription checks require WooCommerce Subscriptions.

Confirm that:

  • WooCommerce and WooCommerce Subscriptions are active
  • the configured subscription product ID is correct
  • the subscription belongs to the logged-in user
  • the subscription status is active or pending-cancel

Other subscription statuses do not grant access.

GitHub Token Is Missing or Rejected

GitHub Release downloads require a token configured under Settings > Secure File Access > GitHub Access.

For private repositories:

  • prefer a fine-grained personal access token limited to the required repositories with Contents: Read-only permission
  • a classic personal access token generally requires the broader repo scope
  • verify any organization approval or SSO authorization requirement
  • replace or remove the saved token from the GitHub Access tab when needed

Leaving the token field blank preserves the existing token.

GitHub Access Is Denied or a Resource Is Missing

GitHub can return similar failures for an inaccessible private repository and a repository, release, tag, archive, or asset that does not exist.

Confirm that:

  • github_repo uses the correct owner/repository value
  • the configured token can access that repository
  • github_tag exactly matches a published stable GitHub Release tag
  • the release is not a draft or prerelease
  • github_asset exactly matches the uploaded ZIP filename when supplied

A Git tag without an associated GitHub Release is not used.

A specified github_tag that does not match a published stable release does not fall back to the latest release. A specified github_asset that does not match an uploaded ZIP asset does not fall back to the generated archive.

Generated Archive or Uploaded Asset

When github_asset is omitted, Secure File Access downloads and rebuilds GitHub's generated ZIP archive for the selected release tag. No uploaded release asset is required.

The resulting ZIP uses the repository name as its filename and places the repository contents directly at the archive root. For example:

private-plugin.zip
├── private-plugin.php
└── ...

When github_asset is supplied, the filename must exactly match an uploaded .zip asset in the selected release.

[file_access github_repo="littlebizzy/private-plugin" github_asset="private-plugin-2.0.0.zip"]

The named asset receives priority and must exist. It redirects directly when GitHub supplies a temporary URL or streams unchanged through WordPress when GitHub returns 200 OK. It is not renamed or rebuilt, and the plugin does not silently substitute the generated source archive.

Generated Archive Cannot Be Prepared

Generated archive processing requires WordPress to download, inspect, extract, stage, rebuild, and stream a temporary ZIP package.

Confirm that:

  • the WordPress temporary directory exists and is writable
  • the server has enough temporary disk space for the source ZIP, extracted files, and rebuilt ZIP
  • PHP can create ZIP archives through ZipArchive or WordPress's bundled PclZip library
  • the generated GitHub archive is complete and valid
  • no security or hosting rule blocks temporary files, archive extraction, or streamed responses
  • the request has enough execution time to download and rebuild the package

Secure File Access requires exactly one root directory in the generated archive. It rejects:

  • empty or malformed ZIP files
  • multiple top-level roots
  • files placed directly at the archive root
  • absolute paths, parent-directory traversal, Windows drive paths, or backslash paths
  • symbolic links

The plugin removes GitHub's generated outer directory and keeps the repository name as the ZIP filename. It does not modify the files or relative paths inside the repository tree.

Uploaded Asset Cannot Be Streamed

A direct 200 OK uploaded asset requires WordPress to write the unchanged ZIP into a private temporary workspace before sending it to the user.

Confirm that:

  • the WordPress temporary directory exists and is writable
  • the server has enough temporary disk space for the uploaded ZIP
  • no security or hosting rule blocks temporary files or streamed responses
  • the request has enough execution time to download and stream the asset

This temporary-file path is used only when GitHub returns the ZIP body directly. Temporary redirects continue to transfer the asset from GitHub to the authorized browser.

Local ZIP Response Cannot Be Sent

Generated archives and direct 200 OK uploaded assets use the same local ZIP sender. Secure File Access refuses the response rather than risking a corrupted or fully buffered ZIP when response headers were already sent or an active output buffer cannot be removed.

Check for:

  • PHP warnings, notices, or whitespace output before the download response
  • a UTF-8 byte-order mark or other output in a plugin or theme PHP file
  • a plugin, theme, host rule, or proxy that sends response headers early
  • a non-removable output buffer created by another plugin or the hosting stack

The plugin closes the temporary file and removes its private workspace when this guard is triggered. Fix the early output or buffering source, reload the page, and use a newly generated protected link.

Downloaded ZIP Has the Wrong Layout

Generated archives should download as repository.zip with repository files and directories directly at the ZIP root.

If the old GitHub-generated name such as owner-repository-tag-hash.zip appears, or the ZIP still contains another repository-named wrapper folder:

  • confirm that Secure File Access 1.6.2 or later is active
  • confirm that github_asset is omitted
  • reload the page to create a new protected link
  • clear any full-page or object cache that preserved an older shortcode response

Explicitly uploaded assets keep the filename and internal structure chosen by their publisher.

Temporary Files Are Left Behind

Temporary workspace paths are unique per request and registered for shutdown cleanup. The plugin also removes the workspace immediately after a completed local stream or redirect fallback when possible.

Temporary files can remain when PHP or the server process is terminated before shutdown handlers run. Remove abandoned sfa-... directories from the configured WordPress temporary directory only after confirming that no download request is using them.

Generated archives and direct 200 OK uploaded assets are not cached, so persistent ZIP packages are not expected.

GitHub Rate Limit or Temporary Failure

The plugin distinguishes GitHub rate limits and temporary GitHub server failures without displaying API response bodies.

It does not automatically retry failed requests. Reload the WordPress page later to create a new protected link and try again.

GitHub Download Response Is Unsupported

The generated-archive API request must return a temporary redirect. A direct ZIP body from that endpoint is rejected because generated archives require the validated temporary-URL normalization flow.

An uploaded-asset API request may return either a temporary redirect or a direct 200 OK ZIP body. Other response forms are rejected.

Every temporary URL must:

  • use HTTPS
  • include a valid host
  • contain no embedded username or password
  • pass WordPress URL safety validation

For a generated archive, WordPress downloads the validated temporary URL and rebuilds the package locally. For an uploaded asset, the authorized browser follows a validated redirect or WordPress streams a direct 200 OK response unchanged through its private workspace.

Protected Link Is Invalid or Expired

This download link is invalid or has expired. can mean that:

  • more than 15 minutes passed
  • the link already completed a successful redirect
  • a local GitHub ZIP was already prepared for that link
  • the temporary record was removed by WordPress or an object cache
  • the stored record is incomplete

Reload the page to generate a new link. Protected links cannot be transferred between user accounts.

Plugin Deactivation or Deletion

Deactivation preserves all settings.

Deleting the plugin removes only the saved sfa_github_token, including per-site tokens across Multisite. Other saved options are preserved for possible reinstallation.

See Shortcode for attributes and examples, Settings for saved defaults and credentials, and Downloads for the complete protected-link flow.