Can't sync to SD card Android 10

Hello!

I’ve checked out the github FAQ already, and as far as I can tell, Syncthing should be able to write to an SD card on Android 10.

However I do get the error that writing to SD cards is not possible on my Android version.

I’m on Syncthing Android version 1.22.1.1 on a Samsung SM-G960F. The SD card is encrypted if that matters.

So my question is either how to fix this, or if the FAQ is not fully up to date.

I can confirm that the FAQ is correct with regards to SD cards on Android. My Motorola phone had Android 10 and then was upgraded to 11 – I’ve had no issues using Syncthing with my SD card with both versions. An older Motorola phone that is pre-Android 10 could be used by Android but direct access by 3rd-party apps was complicated.

One big change starting with Android 10 (aka, “Q”) is storage security. For details, see a Google blog post from 2019: Android Q Scoped Storage: Best Practices and Updates

Starting with Android 10, Syncthing and all other Android apps by default can only access data in their individual apps directories. So in order for Syncthing to write anywhere else it has to be granted access via Android’s Storage Access Framework (SAF).

For various reasons, I encrypt individual files rather than my entire SD card so I don’t know how full disk encryption would affect Syncthing. But assuming it’s not the problem, the first thing is to see how your Samsung SM-G960F sees the SD card (in the past, Samsung has had some quirky ways of handling external storage).

Use a file manager that provides the option to copy the pathname of a directory. One of the best I’ve used is Material Files.

After granting Material Files access to your SD card, make a new directory as a test, then tap the more/hamburger icon (3 vertical dots) on the right and select “Copy path” from the menu. Here’s a screenshot:

image

Please paste the copied pathname into a reply to this post.

(If Material Files isn’t able to access your SD card, then Syncthing won’t either.)

After adding the SD card to Material Files, the path it provides is document:///content://com.android.externalstorage.documents/tree/3188-7BD1%253A?/Test

Trying to sync the path with Syncthing yields the different, following path /storage/3188-7BD1/Test

Edit: decrypting the SD card, just in case this is the issue, and im wasting everyones time.

Can you make sure that Syncthing has access to all files in the Android permission settings? A screenshot showing Syncthing permissions would be welcome.

Using encryption or not should be irrelevant here. I always use encryption myself and have had no problems accessing SD cards with Syncthing.

It is German, however I hope it still is clear from context. No camera/location permission, storage permission is granted.

What is shown when you click “Speicher”? Does it look like in the screenshot below?

My menu looks less granular and more simplified.

Edit: the weirdest thing is, I know this used to work, I used to sync my music library from my Nas to my SD card with Syncthing. When my Nas died I didn’t bother to set it up again, but now I have two new albums I wanna copy over, so I did set it up again on my Nas, it even recognised my old configuration and I didn’t have to do anything. But now it just doesn’t sync from my Nas to the phone

This is how the process looks like in Android 11 (also Samsung) when installing Syncthing for the first time.

There is also “All files access” in special permissions.

I’m not sure all of this is available and/or looks the same in Android 10 though.

It looks quite different on Android 10. I’ve reset the app went through the initial setup again.

Pop-up for granting the permission

Trying to sync a folder on the SD card afterwards leads to the same error. Weirdly enough, Syncthing clearly writes to the SD card, creating the .stfolder

What does Syncthing on your NAS says about the status of the sync? (screenshot of the web GUI would be helpful)

Well, it syncs just fine. Stuff I do on the phone gets applied on my Nas.

The 114 elements it can’t sync are the music album.

And this is the exact error I get in the Syncthing app

(It’s the root folder of the SD card, I know that isn’t best practice, and would defeat the purpose of encrypting the SD card, if my Nas wasn’t encrypted as well. However that has the neat side effect of also transferring pictures/videos straight to my Nas. This however isn’t the issue, as arbitrary folders on the SD card exhibitit the same behaviour)

Edit 1: spelling, sorry half asleep already

Edit 2: Also, again sorry for the German GUI

This should really have been mentioned at the very beginning. Despite the “all files access” permission, Android still restricts a few selected paths (like the aforementioned root path and also other app’s data in Android/data). You will need to run Syncthing as root if you want to sync the root path of the SD card.

So, that’s the issue.

Beginning with Android 10, full-disk encryption is no longer permitted, only file-based encryption is allowed on new devices (upgraded devices depend on the manufacturer).

An easy way to tell if Android is using full-disk or file-based encryption:

  1. Power down the phone.
  2. Turn it back on.

If Android prompts for your pin/password/pattern before it will start booting, it’s full-disk encryption (i.e., single encryption key). But if Android boots up and you can see your wallpaper/background/clock/status by the time the screen lock appears, it’s file-based encryption.

On Android 10 and up, FUSE provides granular access to storage with extra security features. The root of the SD card is a protected space so an app can start from the root and possibly read everything below it, but it cannot be granted write permission starting from the root. This is what happens when I try to add a new folder in Syncthing with the root of an (unencrypted) SD card on Android 10/11 (my Motorola phone previously ran 10 before upgrading to 11):

No worries… :grinning: … Google’s Translate app does a pretty amazing job of translating what it sees from the camera in real-time.

In your most recent screenshot, below the “Folder type” section in the Syncthing app, it says “Files are read-only on this device”“Your Android version only allows Syncthing read-only access to the selected folder”.

The Samsung SM-G960F, aka. “S9” (a friend of mine had the same model) was released with Android 8/Oreo, then later upgradeable to Android 9, and finally Android 10. Samsung likes to customize Android so the menus tend to look different – sometimes even missing menu options – compared to other brands and even between its own smartphone models.

So, try this:

  1. Revoking file/media access for Syncthing.
  2. Create a new folder on the SD card.
  3. Add a new sync folder in Syncthing, selecting the newly created folder from step 2 so that Android will prompt you for permission.
  4. Grant Syncthing access.
1 Like

Funnily enough, this works just fine for me.

You might also notice the .stfolder on the root Syncthing was able to create. This is the part that is so confusing to me. It clearly has the ability to write.

Just so I understand this correctly, can this folder be in be on the root structure, like “/storage/[ID]/A new folder in root” Syncthing just created? Or does it have to be buried in /storage/[ID]/Android/data/com.nutomic.syncthingandroid/ ?

Because the former is read only, the latter indeed works.

Unfortunately, it’s an artifact of phones that span major changes to Android.

What I’m about to explain assumes the following important caveats:

  • The manufacturer hasn’t licensed Google’s Android and made changes to it while still passing Google Play certification.
  • The manufacturer hasn’t copied AOSP (Android Open Source Project), made significant changes to it and chosen not to get Google Play certifified.

Samsung likes to layer on its own custom UI on top of a customized version of Android. In the earlier years the changes were significant, but over time Google and other forces convinced Samsung to tone it down.

The Samsung Galaxy S9 started out with Android 8, upgraded to Android 9, and then finally Android 10 (unofficially, it’s also upgradeable to Android 11). The upgrade path is very important, and part of the reason for the problem you’re experiencing.

Officially, Android 9 and earlier did not support apps writing directly to SD cards. Android could use a SD card to extend the main storage, and apps such as media players, file managers, file transfer and so on could read from a SD card, but not arbitrarily write to one.

Now, some manufacturers who customized Android bolted on some workarounds to make writing possible – besides having had several Android phones, I also have tablets and Android sticks that turn a monitor/TV into an Android computer.

Circling back, the reason why you’re seeing conflicting results on your S9 is because although your phone reports that it’s running Android 10, it’s not the same as if it was factory installed.

As your S9 was upgraded from Android 9 (apps unable to directly write to a SD card) to Android 10 (writing allowed), your phone ended up with a hybrid Android. It’s like doing an in-place upgrade of Windows from 8 to 10, macOS from 12 to 13, or even Linux. The result isn’t perfect.

FUSE is a kernel module that runs in kernel space and a driver that runs in user space. The kernel module needs to plug into the running kernel so it needs to be built against it.

Because of the need for Android to support the hardware, the Android kernel can be locked to a specific version. Everything around it such as program libraries, new directory paths, etc. gets upgraded but it’s still running an older kernel (maybe not the same one, but also not the one that is in the stock Android). Google doesn’t require that upgraded phones meet all of the new requirements – including the ability to use FUSE for storage emulation.

It all means you won’t necessarily see the same results and/or or options as I and others do on their phones that report to be “Android 10” or “Android 11”.

For context, my phone is made by Motorola, but it’s a “Android One” edition. Motorola released some of its phones with both Android One and their custom Android. I prefer the Android One versions because it’s close to stock Android (looks very close to a Google Pixel). The manufacturer is only allowed to bundle in a limited selection of apps and tweaks for special hardware so the phones behave as described by the Android documentation.

Yes, that’s because it’s Android 10 (or higher) – and the .stfolder was created by Syncthing.

If you pick an arbitrary folder, or create one with a file manager, consider which apps “own” each of those folders? :smirk:

Maybe this will help understand it a bit better…

On a Linux desktop or server, when FUSE is used by a user to mount a volume for reading/writing, not even the root user can access the mounted volume. So when a user opens an encrypted folder, the user has pretty good assurances that no other user can access its contents because it’s being sandboxed by the Linux kernel. At its core, Android is a Linux system.

Similiary, on a Windows machine, when a regular user maps an authenticated network drive share, the Administrative user cannot access the drive letter in use by the user.

Same goes for macOS.

/storage/[ID]/Android/data/com.nutomic.syncthingandroid/ works because it’s a system managed folder designated for the Syncthing app. If you tried to select a folder belonging to another app to write into under /storage/[ID]/Android/data/, it would most likely fail (per the caveats I mentioned earlier).

With Android 10 and up, you can start with a folder at the root (as long as it’s not a system folder). If you take another look at the screenshot I posted, there’s a “Jukebox” folder. I have a few album folders, a music video folder, and so on. I created the “Jukebox” folder with the Material Files app, then when I selected it in Syncthing, Android asked me to grant Syncthing access to it.

If Android allowed an app write access to the root of the SD card and all of its subfolders, the app would have the ability to modify files under /storage/[ID]/Android/data/, which could contain access tokens and other private data.

Oh yeah, totally get that. But at least in my mind you shouldn’t be able to create a folder if you don’t have write access to the directory you are creating it in. So if Syncthing can create the .stfolder on the root of the SD card, it has to have write access to the root. Or am I completely missing something and getting insane? But let’s not get too hung up on the “entire root” part, if it worked for folders I created on the SD card root, I wouldn’t be complaining. It would be tedious to set it up for all the folders I wanted to sync, but it would be an acceptable workaround.

Now this is my issue. This part doesn’t work for me. Neither deleting local files and clearing the cache nor a complete reinstall of Syncthing fixed this, the only folder on the SD Card I can get write access to is com.nutomic.syncthingandroid.

As you’ve explained, this could very well be an artifact of how Samsung decided to upgrade the S9 to Android 10, meaning that in this specific way my Android 10 behaves more like Android 9, so I have to use the Android 9 workaround documented in the FAQ. Which would be very disappointing, but not necessarily an issue with Syncthing.

Okay, I did a quick sanity check, and tried a different syncing solution, Resilio. And there it works just fine (even the access to the SD Card root!). Now I am obviously not an Android dev, and Resilio isn’t OpenSource, so no idea what forbidden arcane magic they used to make that work. I really want to get rid of Resilio tho, because Syncthing is much more customizable.

Admittedly I haven’t read everything - there’s too much text here, so sorry if I am asking the obvious: Is the problem just this popup that says you can’t sync? Then I’d use the advanced folder picker or web UI to add the sd card root as a send-receive folder and see if it works then. Might be that there’s still some now incorrect check in the folder picker logic that says it’s not possible.

No! The main problem is, that I can’t get write access to my SD card, apart from /storage/[ID]/Android/data/com.nutomic.syncthingandroid/

Now, according to the FAQ, this is the workaround for Android 9, however I’m running Android 10, and should be able to write to folders on my SD just fine.

Maybe the FAQs is wrong. My understanding is still that scoped storage shouldn’t apply in android 10 (app opts-out, there’s no “all file access” in 10). However maybe that opt-out isn’t working anymore on 10 as well, as scoped storage was enforced when targeting 11. So unless someone else on android 10 can confirm sd card access works, the thing to change here might just be our FAQ.