Penny for Craft CMS

Troubleshooting

The recipient says the link does not work

Open the invite in Penny → Invites. The status in the side pane and the What has happened table usually answer it. Every refused visit to a real link is logged as "Access denied" with the reason.

What the recipient saw tells you which case it is:

They sawWhat happenedWhat to do
This link is not valid.The key matches no invite. Usually the link was cut short when it was copied or wrapped by an email client, or it has since been re-issued.Check they have the whole link. If in doubt, re-issue and send the new one.
This link has expired.The deadline passed.Re-issue it. The new link gets a fresh deadline.
This link has been turned off.It was revoked.Re-issue it if they should have it back.
This link has already been used.It was submitted, or it is a view link and somebody pressed Open the page.Make a new invite. A submitted or viewed invite cannot be re-issued.
Too many attempts. Try again later.Their IP address has made too many wrong guesses.See below.
This link could not be opened.A control panel invite could not create or sign in its temporary account.See below.

A link that never existed and a link that is malformed get the same answer on purpose. Telling them apart would only help somebody guessing.

"Couldn't re-issue this link"

The invite has been submitted, or it is a view link that has been viewed, including one that was revoked afterwards. Its content is on the site, or waiting for review, or the page has been seen, and the invite is finished. Make a new invite for any further changes, or another view link.

"Too many attempts"

Each IP address gets Failed attempts allowed per hour wrong or malformed keys (20 by default) before Penny stops answering it. A correct key never counts.

This can catch a whole office behind one IP address if somebody there has been pasting broken links. The counter clears an hour after the last failed attempt, and opening a valid link clears it too. A valid link always opens, even once the limit is reached: the limit is there to stop guessing, and somebody holding the real key is not guessing. You can raise the limit, or set it to 0 to turn it off, under Penny → Settings → Housekeeping. The counter lives in Craft's data cache, so clearing that cache also resets it.

The link asks the recipient to log in

The Penny page only answers while the system is on. If System status is off under Settings → General, the recipient is sent to the login screen like any other visitor. Turn the system on, or wait until it is back.

The link on the site gives a 404

The pretty link is /<prefix>/<key>, with the prefix from Invite URL prefix. Check the setting has a value, that nothing else on the site claims the same path, and that the link the recipient has uses the prefix you have now. Changing the prefix does not update links already sent.

"This link could not be opened" on a control panel invite

Penny could not create the temporary account or sign it in. The usual causes:

  • Craft Solo. Solo allows one user, and the control panel surface needs a second. Switch the invite to Penny page.
  • Pro is not active. A control panel invite on Lite opens on the Penny page instead, so this means something else went wrong. Check the Craft log for lines from the penny category, which say why the account could not be saved.

Saving a view link is refused

MessageWhy
View links are a Pro feature.View once needs Pro.
A view link shows one thing.It has more than one target. Remove the others, or make one view link per page.
A view link needs something that already exists.The target is set to create a new entry.
"" has no page on this site to show.</td><td>The element has no URL on the invite's site. Check the section has a URI format for that site, or pick another site under <strong>Site</strong>.</td></tr> </tbody> </table> <h2>A view link says it has already been used, but the recipient never saw it</h2> <p>Somebody else pressed <strong>Open the page</strong> first. Opening the link does not spend it, so a mail scanner or a chat preview is not the cause; a person in a browser is. Usually the email was forwarded, the link was opened from a shared inbox or by an assistant, or the recipient pressed the button on one device and is now trying another.</p> <p>The invite's <strong>What has happened</strong> table has a "Link viewed" line with the time and IP address of the browser that pressed it, which is usually enough to tell who. Make a new view link for the recipient.</p> <h2>A view link opened, but on reload or on another device it says it has been used</h2> <p>The page is tied to the browser that pressed <strong>Open the page</strong>, for the <strong>Viewing window</strong> (30 minutes by default).</p> <ul> <li><strong>Another browser or device</strong>, or the page's address pasted somewhere else, gets "This link has already been used." The page's address carries a token, but the token only works together with a cookie set in the browser that opened it.</li> <li><strong>A private window</strong> counts as another browser, and so does the same browser after its cookies have been cleared.</li> <li><strong>After the window</strong>, the page says "This page has closed." The address keeps answering for a day after that, so it can say so; after that Craft answers it with its own "Invalid token" error.</li> <li><strong>"This link has been turned off."</strong> means the invite was revoked.</li> </ul> <p>If they need longer, raise <strong>Viewing window</strong> under <strong>Penny → Settings → View links</strong> and make them a new link. A changed setting does not reopen a link that has already closed.</p> <h2>A view link shows the live page, an old copy, or a 404</h2> <p>The page is served at the element's own URL with a <code>token</code> query parameter, and it is only right if that request reaches Craft. Craft does not cache token requests, and Blitz skips them by default. A CDN, reverse proxy or full-page cache that ignores query strings will answer with whatever it has cached for that URL: the public version of the page, or a 404 if the entry is not live yet. Set it to pass any request with a <code>token</code> parameter through to Craft uncached.</p> <p>A disabled entry or a draft is not the cause by itself. Penny routes the request the way Craft routes a preview, so the page's URL resolves to the shared entry, and your template receives it as <code>entry</code>, whatever its status. A template that looks the entry up again with its own query, rather than using <code>entry</code>, may not find a disabled one, and could 404 on that.</p> <h2>"Share once" is missing from an edit screen</h2> <p>The button only appears when:</p> <ul> <li>Penny is on Pro,</li> <li>you have the <strong>Create and edit invites</strong> permission,</li> <li>the element has a URL on its site (an entry in a section with no URI format has none), and</li> <li>you are not inside an invited control panel session.</li> </ul> <p>It is also left off revisions. If the button is there but refuses, you may not have permission to view that element, or that draft if it is somebody else's.</p> <h2>Saving an invite says "Control panel sessions are a Pro feature"</h2> <p>On Lite, every invite has to use the Penny page. If new invites keep picking the control panel, <strong>Default surface</strong> in settings (or <code>defaultSurface</code> in <code>config/penny.php</code>) is set to <code>cp</code>. Set it back to <code>hosted</code>.</p> <h2>The recipient submitted, but nothing changed on the site</h2> <ul> <li><strong>Hold for review is on.</strong> The invite shows <strong>Awaiting review</strong>. Click <strong>Approve and publish</strong>. You need the <strong>Approve submitted content</strong> permission to see the button.</li> <li><strong>It was a new-entry target.</strong> New entries are created disabled, so a submitted one exists but is not live. Find it in its section and enable it.</li> <li><strong>It was a control panel invite that was never handed in.</strong> The recipient worked in Craft's own editor and closed the tab without clicking <strong>I'm finished, hand it in</strong>. Their draft is in the entry's drafts; apply it yourself, or ask them to open the link again and hand it in.</li> </ul> <h2>"Something on this form could not be saved"</h2> <p>A save failed because of a field the recipient was not given, and Penny does not show people errors about fields they cannot see. The usual cause is a required field outside the scope that is empty on the element. Either fill that field in yourself, or add it to the invite's fields.</p> <h2>A field changed back after a control panel session</h2> <p>That is the scope working. On the control panel surface Craft's editor can show fields that are not in the invite's scope, and Penny puts any change to them back before the save reaches the database. Add the field to the target's scope if they should be able to change it.</p> <h2>A relation field or asset picker on the Penny page shows nothing, or too little</h2> <p>Field inputs render as the <strong>Acting user</strong>, which is the invite's author unless you set one. A relation field offers what that user can see. Set an acting user whose permissions cover the sources the field uses. What the recipient can actually save is still limited by the invite's scope.</p> <h2>The invite email did not arrive</h2> <p>Check, in order:</p> <ol start="1"> <li>Penny is on Pro. Lite does not send email.</li> <li>The invite has a <strong>Recipient email</strong>.</li> <li><strong>Send the link when an invite is created</strong> is on, if you expected it on creation. Otherwise use <strong>Email a fresh link</strong> on the invite.</li> <li>The invite's <strong>What has happened</strong> table shows "Link sent". If it does, Craft handed the message to your mail transport, and the problem is delivery. Send a test from <strong>Settings → Email</strong>.</li> <li>If there is no "Link sent", look in the Craft log for lines from the <code>penny</code> category.</li> </ol> <h2>Reminders did not go out</h2> <p><code>php craft penny/invites/remind</code> only reminds invites that:</p> <ul> <li>are live,</li> <li>have a recipient email,</li> <li>have an expiry date within the reminder window, and</li> <li><strong>have not been opened yet</strong>.</li> </ul> <p>It also needs Pro, and <strong>Remind this many days before expiry</strong> above 0 (or <code>--days</code> on the command). Run it with <code>--dry-run</code> to see who it would pick.</p> <h2>Nobody got a submission notice</h2> <p>Submission notices are Pro. They go to the invite's <strong>Notify on submission</strong> addresses, or to the default ones in settings if the invite has none. Addresses that are not valid email addresses are skipped.</p> <h2>Temporary users are still in the user list</h2> <p>A control panel account is removed as soon as the recipient hands in, or when its invite is revoked or deleted. If the invite simply expires, it goes the next time Craft's garbage collection runs. To do it now:</p> <pre><code class="language-sh">php craft penny/invites/prune </code></pre> <p>If <strong>Delete the temporary account afterwards</strong> is off, the accounts are kept on purpose, suspended. They have no password and cannot sign in.</p> </div> <nav class="flex justify-between gap-4 pt-8 mt-16 border-t border-white/5"> <a href="https://justinholt.com/plugins/craft-penny/docs/usage/" class="text-sm text-off-white/50 hover:text-off-white"> ← Usage </a> <a href="https://justinholt.com/plugins/craft-penny/docs/faq/" class="text-sm text-right text-off-white/50 hover:text-off-white"> FAQ → </a> </nav> </article> </div> </div> </div> </main> <footer class="border-t bg-charcoal-lighter border-white/5"> <div class="px-6 py-16 mx-auto max-w-7xl"> <div class="grid grid-cols-1 gap-12 md:grid-cols-3"> <div> <div class="flex items-center gap-3 mb-4"> <img src="https://justinholt.com/images/plugins/penny.svg" alt="" class="w-8 h-8" width="32" height="32" loading="lazy"> <span class="text-2xl font-display text-off-white">Penny for Craft CMS</span> </div> <p class="mb-4 text-sm leading-relaxed text-off-white/50">A single-use link to exactly the fields you chose</p> <p class="text-sm text-off-white/50"> A Craft CMS plugin by <a href="https://justinholt.com/" class="transition-colors text-off-white hover:text-accent">Justin Holt</a> </p> </div> <div> <h2 class="mb-4 text-xl font-display text-off-white">Quick Links</h2> <ul class="space-y-2 text-sm"> <li><a href="https://justinholt.com/plugins/craft-penny/" class="transition-colors text-off-white/50 hover:text-off-white">Overview</a></li> <li><a href="https://justinholt.com/plugins/craft-penny//docs/installation" class="transition-colors text-off-white/50 hover:text-off-white">Installation</a></li> <li><a href="https://justinholt.com/plugins/craft-penny//docs/configuration" class="transition-colors text-off-white/50 hover:text-off-white">Configuration</a></li> <li><a href="https://justinholt.com/plugins/craft-penny//docs/usage" class="transition-colors text-off-white/50 hover:text-off-white">Usage</a></li> <li><a href="https://plugins.craftcms.com/penny?craft5" class="transition-colors text-off-white/50 hover:text-off-white" target="_blank" rel="noopener">Plugin Store</a></li> <li><a href="https://github.com/justinholtweb/craft-penny" class="transition-colors text-off-white/50 hover:text-off-white" target="_blank" rel="noopener">GitHub</a></li> </ul> </div> <div> <h2 class="mb-4 text-xl font-display text-off-white">More Plugins</h2> <ul class="grid grid-cols-2 gap-x-4 gap-y-1.5 text-sm"> <li> <a href="https://justinholt.com/plugins/craft-abacus/" class="transition-colors text-off-white/50 hover:text-off-white">Abacus</a> </li> <li> <a href="https://justinholt.com/plugins/craft-airwave/" class="transition-colors text-off-white/50 hover:text-off-white">Airwave</a> </li> <li> <a href="https://justinholt.com/plugins/craft-alarmclock/" class="transition-colors text-off-white/50 hover:text-off-white">Alarm Clock</a> </li> <li> <a href="https://craft-appleseed.com" class="transition-colors text-off-white/50 hover:text-off-white">Appleseed</a> </li> <li> <a href="https://justinholt.com/plugins/craft-archie/" class="transition-colors text-off-white/50 hover:text-off-white">Archie</a> </li> <li> <a href="https://craft-archive.com" class="transition-colors text-off-white/50 hover:text-off-white">Archive</a> </li> <li> <a href="https://justinholt.com/plugins/craft-awesemo/" class="transition-colors text-off-white/50 hover:text-off-white">Awesemo</a> </li> <li> <a href="https://justinholt.com/plugins/craft-bandage/" class="transition-colors text-off-white/50 hover:text-off-white">Bandage</a> </li> <li> <a href="https://justinholt.com/plugins/craft-bed/" class="transition-colors text-off-white/50 hover:text-off-white">Bed</a> </li> <li> <a href="https://justinholt.com/plugins/craft-bee/" class="transition-colors text-off-white/50 hover:text-off-white">Bee</a> </li> <li> <a href="https://justinholt.com/plugins/craft-bird/" class="transition-colors text-off-white/50 hover:text-off-white">Bird</a> </li> <li> <a href="https://justinholt.com/plugins/craft-blackhole/" class="transition-colors text-off-white/50 hover:text-off-white">Black Hole</a> </li> <li> <a href="https://justinholt.com/plugins/craft-blaster/" class="transition-colors text-off-white/50 hover:text-off-white">Blaster</a> </li> <li> <a href="https://justinholt.com/plugins/craft-book/" class="transition-colors text-off-white/50 hover:text-off-white">Book</a> </li> <li> <a href="https://justinholt.com/plugins/craft-boomerang/" class="transition-colors text-off-white/50 hover:text-off-white">Boomerang</a> </li> <li> <a href="https://justinholt.com/plugins/craft-bouncer/" class="transition-colors text-off-white/50 hover:text-off-white">Bouncer</a> </li> <li> <a href="https://craft-caffeine.com" class="transition-colors text-off-white/50 hover:text-off-white">Caffeine</a> </li> <li> <a href="https://justinholt.com/plugins/craft-chunky/" class="transition-colors text-off-white/50 hover:text-off-white">Chunky</a> </li> <li> <a href="https://justinholt.com/plugins/craft-cleanair/" class="transition-colors text-off-white/50 hover:text-off-white">Clean Air</a> </li> <li> <a href="https://justinholt.com/plugins/craft-coinpurse/" class="transition-colors text-off-white/50 hover:text-off-white">Coin Purse</a> </li> <li> <a href="https://justinholt.com/plugins/craft-compare/" class="transition-colors text-off-white/50 hover:text-off-white">Compare</a> </li> <li> <a href="https://justinholt.com/plugins/craft-comparer/" class="transition-colors text-off-white/50 hover:text-off-white">Comparer</a> </li> <li> <a href="https://craft-controltower.com" class="transition-colors text-off-white/50 hover:text-off-white">Control Tower</a> </li> <li> <a href="https://justinholt.com/plugins/craft-corndog/" class="transition-colors text-off-white/50 hover:text-off-white">Corndog</a> </li> <li> <a href="https://justinholt.com/plugins/craft-csr/" class="transition-colors text-off-white/50 hover:text-off-white">CSR</a> </li> <li> <a href="https://justinholt.com/plugins/craft-datevz/" class="transition-colors text-off-white/50 hover:text-off-white">Datevz</a> </li> <li> <a href="https://justinholt.com/plugins/craft-digits/" class="transition-colors text-off-white/50 hover:text-off-white">Digits</a> </li> <li> <a href="https://craft-diploma.com" class="transition-colors text-off-white/50 hover:text-off-white">Diploma</a> </li> <li> <a href="https://craft-dispatch.com" class="transition-colors text-off-white/50 hover:text-off-white">Dispatch</a> </li> <li> <a href="https://justinholt.com/plugins/craft-donky/" class="transition-colors text-off-white/50 hover:text-off-white">Donky</a> </li> <li> <a href="https://justinholt.com/plugins/craft-eat/" class="transition-colors text-off-white/50 hover:text-off-white">Eat</a> </li> <li> <a href="https://justinholt.com/plugins/craft-econz/" class="transition-colors text-off-white/50 hover:text-off-white">Econz</a> </li> <li> <a href="https://justinholt.com/plugins/craft-fjord/" class="transition-colors text-off-white/50 hover:text-off-white">Fjord</a> </li> <li> <a href="https://craft-freelink.com" class="transition-colors text-off-white/50 hover:text-off-white">FreeLink</a> </li> <li> <a href="https://craft-freelogs.com" class="transition-colors text-off-white/50 hover:text-off-white">Freelog</a> </li> <li> <a href="https://craft-freenav.com" class="transition-colors text-off-white/50 hover:text-off-white">FreeNav</a> </li> <li> <a href="https://justinholt.com/plugins/craft-freshh/" class="transition-colors text-off-white/50 hover:text-off-white">Freshh</a> </li> <li> <a href="https://craft-garrison.com" class="transition-colors text-off-white/50 hover:text-off-white">Garrison</a> </li> <li> <a href="https://craft-headcount.com" class="transition-colors text-off-white/50 hover:text-off-white">Headcount</a> </li> <li> <a href="https://craft-heat.com" class="transition-colors text-off-white/50 hover:text-off-white">Heat</a> </li> <li> <a href="https://justinholt.com/plugins/craft-holding/" class="transition-colors text-off-white/50 hover:text-off-white">Holding</a> </li> <li> <a href="https://craft-holmes.com" class="transition-colors text-off-white/50 hover:text-off-white">Holmes</a> </li> <li> <a href="https://craft-homer.com" class="transition-colors text-off-white/50 hover:text-off-white">Homer</a> </li> <li> <a href="https://craft-icecube.com" class="transition-colors text-off-white/50 hover:text-off-white">Icecube</a> </li> <li> <a href="https://justinholt.com/plugins/craft-jarhead/" class="transition-colors text-off-white/50 hover:text-off-white">Jarhead</a> </li> <li> <a href="https://justinholt.com/plugins/craft-knox/" class="transition-colors text-off-white/50 hover:text-off-white">Knox</a> </li> <li> <a href="https://craft-leads.com" class="transition-colors text-off-white/50 hover:text-off-white">Leads</a> </li> <li> <a href="https://justinholt.com/plugins/craft-lexies/" class="transition-colors text-off-white/50 hover:text-off-white">Lexies</a> </li> <li> <a href="https://craft-lightning.com" class="transition-colors text-off-white/50 hover:text-off-white">Lightning</a> </li> <li> <a href="https://craft-live.com" class="transition-colors text-off-white/50 hover:text-off-white">Live</a> </li> <li> <a href="https://craft-microscope.com" class="transition-colors text-off-white/50 hover:text-off-white">Microscope</a> </li> <li> <a href="https://craft-nuke.com" class="transition-colors text-off-white/50 hover:text-off-white">Nuke</a> </li> <li> <a href="https://craft-owl.com" class="transition-colors text-off-white/50 hover:text-off-white">Owl</a> </li> <li> <a href="https://justinholt.com/plugins/craft-palletizr/" class="transition-colors text-off-white/50 hover:text-off-white">Palletizr</a> </li> <li> <a href="https://justinholt.com/plugins/craft-passer/" class="transition-colors text-off-white/50 hover:text-off-white">Passer</a> </li> <li> <a href="https://craft-peek.com" class="transition-colors text-off-white/50 hover:text-off-white">Peek</a> </li> <li> <a href="https://craft-pigeon.com" class="transition-colors text-off-white/50 hover:text-off-white">Pigeon</a> </li> <li> <a href="https://craft-puppy.com" class="transition-colors text-off-white/50 hover:text-off-white">Puppy</a> </li> <li> <a href="https://craft-queuebert.com" class="transition-colors text-off-white/50 hover:text-off-white">Queuebert</a> </li> <li> <a href="https://craft-rabbits.com" class="transition-colors text-off-white/50 hover:text-off-white">Rabbits</a> </li> <li> <a href="https://craft-rat.com" class="transition-colors text-off-white/50 hover:text-off-white">Rat</a> </li> <li> <a href="https://justinholt.com/plugins/craft-sanka/" class="transition-colors text-off-white/50 hover:text-off-white">Sanka</a> </li> <li> <a href="https://justinholt.com/plugins/craft-scrub/" class="transition-colors text-off-white/50 hover:text-off-white">Scrub</a> </li> <li> <a href="https://justinholt.com/plugins/craft-sevvies/" class="transition-colors text-off-white/50 hover:text-off-white">Sevvies</a> </li> <li> <a href="https://craft-showtime.com" class="transition-colors text-off-white/50 hover:text-off-white">Showtime</a> </li> <li> <a href="https://justinholt.com/plugins/craft-sidepipe/" class="transition-colors text-off-white/50 hover:text-off-white">Sidepipe</a> </li> <li> <a href="https://craft-smoke.com" class="transition-colors text-off-white/50 hover:text-off-white">Smoke</a> </li> <li> <a href="https://craft-sourdough.com" class="transition-colors text-off-white/50 hover:text-off-white">Sourdough</a> </li> <li> <a href="https://craft-spectacles.com" class="transition-colors text-off-white/50 hover:text-off-white">Spectacles</a> </li> <li> <a href="https://justinholt.com/plugins/craft-speculatr/" class="transition-colors text-off-white/50 hover:text-off-white">Speculatr</a> </li> <li> <a href="https://craft-stars.com" class="transition-colors text-off-white/50 hover:text-off-white">Stars</a> </li> <li> <a href="https://craft-stub.com" class="transition-colors text-off-white/50 hover:text-off-white">Stub</a> </li> <li> <a href="https://craft-telescope.com" class="transition-colors text-off-white/50 hover:text-off-white">Telescope</a> </li> <li> <a href="https://craft-tidytags.com" class="transition-colors text-off-white/50 hover:text-off-white">Tidy Tags</a> </li> <li> <a href="https://justinholt.com/plugins/craft-tokr/" class="transition-colors text-off-white/50 hover:text-off-white">Tokr</a> </li> <li> <a href="https://justinholt.com/plugins/craft-toss/" class="transition-colors text-off-white/50 hover:text-off-white">Toss</a> </li> <li> <a href="https://justinholt.com/plugins/craft-trackr/" class="transition-colors text-off-white/50 hover:text-off-white">Trackr</a> </li> <li> <a href="https://craft-transport.com" class="transition-colors text-off-white/50 hover:text-off-white">Transport</a> </li> <li> <a href="https://justinholt.com/plugins/craft-twinsies/" class="transition-colors text-off-white/50 hover:text-off-white">Twinsies</a> </li> <li> <a href="https://craft-update-permissions-reminder.com" class="transition-colors text-off-white/50 hover:text-off-white">Update Permissions Reminder</a> </li> <li> <a href="https://justinholt.com/plugins/craft-vismaz/" class="transition-colors text-off-white/50 hover:text-off-white">Vismaz</a> </li> <li> <a href="https://justinholt.com/plugins/craft-visor/" class="transition-colors text-off-white/50 hover:text-off-white">Visor</a> </li> <li> <a href="https://justinholt.com/plugins/craft-visorr/" class="transition-colors text-off-white/50 hover:text-off-white">Visorr</a> </li> <li> <a href="https://justinholt.com/plugins/craft-waterfall/" class="transition-colors text-off-white/50 hover:text-off-white">Waterfall</a> </li> <li> <a href="https://justinholt.com/plugins/craft-waver/" class="transition-colors text-off-white/50 hover:text-off-white">Waver</a> </li> <li> <a href="https://justinholt.com/plugins/craft-weight/" class="transition-colors text-off-white/50 hover:text-off-white">Weight</a> </li> <li> <a href="https://craft-wink.com" class="transition-colors text-off-white/50 hover:text-off-white">Wink</a> </li> <li> <a href="https://justinholt.com/plugins/craft-yo/" class="transition-colors text-off-white/50 hover:text-off-white">Yo</a> </li> <li> <a href="https://justinholt.com/plugins/craft-zo/" class="transition-colors text-off-white/50 hover:text-off-white">Zo</a> </li> </ul> </div> </div> <div class="flex flex-col items-center justify-between gap-4 pt-8 mt-8 sm:flex-row mt-12 border-t border-white/5"> <p class="text-sm text-off-white/40">© 2026 Justin Holt. All rights reserved.</p> <a href="https://craftcms.com" class="text-sm transition-colors text-off-white/40 hover:text-off-white" target="_blank" rel="noopener"> Built with Craft CMS </a> </div> </div> </footer> <a href="https://justinholt.com/blackhole/" title="Do NOT follow this link or you will be banned from this site!" rel="nofollow" style="display: none;" aria-hidden="true" tabindex="-1"> </a></body> </html>