This page lists common problems and work-arounds.
This page needs expansion! If you encounter a new problem and solve it, feel free to add it here. If you encounter a problem you don't know how to solve, try asking on Stack Overflow, and be sure to add the "sandstorm.io" tag to your question. Or, talk to us on IRC (#sandstorm on libera.chat) or sandstorm-dev.
Note that language-specific issues should be documented in the language-specific guide pages, namely:
Getting a shell in the context of the grain
vagrant-spk enter-grain allows you to run a shell (e.g.
bash) in the context of a grain. This can
illuminate why an app is behaving in a particular way. For details and limitations, read the
docs about the
vagrant-spk enter-grain command.
Clicking a link in the app does not open the link
Sandstorm apps cannot navigate the user away from the app. Therefore, app
authors should set
target="_blank" on links within the app.
A convenient way to do this automatically for all links in the page is to add
the following HTML to your document's
A blank white screen renders where the app should be
This can happen when a Sandstorm app in development doesn't know its correct base URL and serves a HTTP redirect away from the Sandstorm server. Sandstorm blocks that redirect, resulting in a white grain frame.
console in your browser and look for a
violation. If you see a message about navigation being blocked, then
very likely you are seeing this error.
If possible, configure the app to use a base URL of
the empty string. Then it will send HTTP redirects without
specifying a base URL. If that isn't possible, Sandstorm apps should
look at the
Host: header for a base URL.
KeyError: 'getpwuid(): uid not found: 1000'
This is a Python bug. See the Python packaging guide for a work-around.
EROFS or "Read-only filesystem"
/var directory is writable; the rest of the filesystem (which
contains the contents of your app package) is read-only.
If your app wants to write to locations other than
/var, and it's not easy to
change the app's code, one work-around is to create a symlink from the location
you app wants to modify to a location under
/var. This won't work for all
Web apps often use the
ETag HTTP response header to control caching. In Sandstorm, this header is
permitted so long as it follows the HTTP specification's requirement that the header values are
formatted with double-quote marks, like:
ETag: "value" or
Some apps use strings without quotation marks in their ETag headers, such as
ETag: value, which
violates the HTTP standard. Sandstorm does not permit invalid header values because ambiguity can
lead to security problems. Therefore, Sandstorm will drop invalid
ETag headers and will write a
warning to the grain's debug log. Usually, this does not affect app functionality, other than to
reduce the effectiveness of the browser's cache.
HTTP headers are processed within the grain at the sandstorm-http-bridge
layer. Recent versions of
sandstorm-http-bridge drop the header and log a message. In versions
v0.177 and earlier of
sandstorm-http-bridge, invalid ETag data would trigger an exception,
causing the request to fail.
SPK is missing files, but app works in dev mode
Sandstorm packages, when "packed" into an SPK file, must contain all files needed by the app. Those
files are typically specified in
.sandstorm/sandstorm-files.list and detected when the app runs in
dev mode. Further files can be specified via an
alwaysInclude directive in
.sandstorm/sandstorm-pkgdef.capnp. Some apps hard-code all files in
.sandstorm/sandstorm-files.list rather than relying on auto-detection. In any event, if the app
needs a file that is missing in the Sandstorm package, the file must be added.
Note that paths begin without a slash character. For example, to include
path/to/include into the
alwaysInclude line or the
How to identify this error: Sometimes the app will crash (HTTP response code 500 Server Error) if it is affected by this problem. Often a "No such file" or "No such module" error appears in the grain log, similar to the following.
Warning: require_once(path/to/file.php): failed to open stream: No such file or directory
ImportError: No such module requests
How to fix the problem: Our recommendations are as follows.
For Python apps, add the app's virtualenv to alwaysInclude. To do that, look for the
alwaysIncludelist and add
opt/app/env. See the ContactOtter sandstorm-pkgdef.capnp for an example. It is sometimes helpful to also add
usr/lib/python2.7(or the corresponding path for your version of Python).
For nodejs apps, add node_modules to alwaysInclude. See the Duolodo sandstorm-pkgdef.capnp for an example.
For PHP apps, consider adding all of /opt/app to alwaysInclude. See the MediaWiki sandstorm-pkgdef.capnp for an example.
For Ruby apps that use bundler, add the bundle to alwaysInclude. See the lobste.rs sandstom-pkgdef.capnp for an example.
For apps that rely on system libraries, consider using
alwaysIncludeto add more system paths to be snapshotted into the package.
How file auto-detection works. At each launch of
spk dev (equivalently, each launch of
vagrant-spk dev), a FUSE filesystem is created that watches all filesystem operations by the
app. When the
spk dev session terminates, any files that the app
open()d are logged into
.sandstorm/sandstorm-files.list. This skips any files that are merely
stat()d. Because some apps
know their full list of dependencies, the
.sandstorm/sandstorm-pkgdef.capnp file is is not
written if the
alwaysInclude line contains
".", which has the meaning of "include all files that
the app can see." The
meteor platform stack takes advantage of this feature.