diff --git a/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java
index 2b29393703dcb5f57a618ccb4167cf4367054b4a..3aeaab5bd806fad1f5f3f08d8555bfeb4f04cfbd 100644
--- a/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java
+++ b/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java
@@ -291,8 +291,12 @@ class FeedManagerImpl implements FeedManager, Client, EventListener,
 	 * This method is called periodically from a background service.
 	 * It fetches all available feeds and posts new entries to the respective
 	 * blog.
+	 *
+	 * We can not do this within one database {@link Transaction},
+	 * because fetching can take a long time
+	 * and we can not block the database that long.
 	 */
-	private void fetchFeeds() {
+	void fetchFeeds() {
 		LOG.info("Updating RSS feeds...");
 
 		// Get current feeds
@@ -313,12 +317,15 @@ class FeedManagerImpl implements FeedManager, Client, EventListener,
 			} catch (FeedException e) {
 				if (LOG.isLoggable(WARNING))
 					LOG.log(WARNING, e.toString(), e);
+				newFeeds.add(feed);
 			} catch (IOException e) {
 				if (LOG.isLoggable(WARNING))
 					LOG.log(WARNING, e.toString(), e);
+				newFeeds.add(feed);
 			} catch (DbException e) {
 				if (LOG.isLoggable(WARNING))
 					LOG.log(WARNING, e.toString(), e);
+				newFeeds.add(feed);
 			}
 		}
 
diff --git a/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerImplTest.java b/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerImplTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..d8618425113e640b40c8ebf5197d33e4d9c14ba4
--- /dev/null
+++ b/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerImplTest.java
@@ -0,0 +1,135 @@
+package org.briarproject.briar.feed;
+
+import org.briarproject.bramble.api.client.ClientHelper;
+import org.briarproject.bramble.api.client.ContactGroupFactory;
+import org.briarproject.bramble.api.data.BdfDictionary;
+import org.briarproject.bramble.api.data.BdfEntry;
+import org.briarproject.bramble.api.data.BdfList;
+import org.briarproject.bramble.api.db.DatabaseComponent;
+import org.briarproject.bramble.api.db.Transaction;
+import org.briarproject.bramble.api.identity.AuthorId;
+import org.briarproject.bramble.api.identity.LocalAuthor;
+import org.briarproject.bramble.api.sync.Group;
+import org.briarproject.bramble.api.sync.GroupId;
+import org.briarproject.bramble.api.system.Clock;
+import org.briarproject.bramble.test.BrambleMockTestCase;
+import org.briarproject.bramble.test.ImmediateExecutor;
+import org.briarproject.briar.api.blog.Blog;
+import org.briarproject.briar.api.blog.BlogManager;
+import org.briarproject.briar.api.blog.BlogPostFactory;
+import org.briarproject.briar.api.feed.Feed;
+import org.jmock.Expectations;
+import org.junit.Test;
+
+import java.net.UnknownHostException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ScheduledExecutorService;
+
+import javax.net.SocketFactory;
+
+import okhttp3.Dns;
+
+import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
+import static org.briarproject.bramble.test.TestUtils.getRandomId;
+import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEEDS;
+import static org.briarproject.briar.api.feed.FeedManager.CLIENT_ID;
+
+public class FeedManagerImplTest extends BrambleMockTestCase {
+
+	private final ScheduledExecutorService scheduler =
+			context.mock(ScheduledExecutorService.class);
+	private final Executor ioExecutor = new ImmediateExecutor();
+	private final DatabaseComponent db = context.mock(DatabaseComponent.class);
+	private final ContactGroupFactory contactGroupFactory =
+			context.mock(ContactGroupFactory.class);
+	private final ClientHelper clientHelper = context.mock(ClientHelper.class);
+	private final BlogManager blogManager = context.mock(BlogManager.class);
+	private final BlogPostFactory blogPostFactory =
+			context.mock(BlogPostFactory.class);
+	private final FeedFactory feedFactory = context.mock(FeedFactory.class);
+	private final Clock clock = context.mock(Clock.class);
+	private final Dns noDnsLookups = context.mock(Dns.class);
+
+	private final GroupId localGroupId = new GroupId(getRandomId());
+	private final Group localGroup =
+			new Group(localGroupId, CLIENT_ID, getRandomBytes(42));
+	private final GroupId blogGroupId = new GroupId(getRandomId());
+	private final Group blogGroup =
+			new Group(blogGroupId, BlogManager.CLIENT_ID, getRandomBytes(42));
+	private final AuthorId authorId = new AuthorId(getRandomId());
+	private final LocalAuthor localAuthor =
+			new LocalAuthor(authorId, "author", getRandomBytes(2),
+					getRandomBytes(2), 0);
+	private final Blog blog = new Blog(blogGroup, localAuthor, true);
+	private final Feed feed =
+			new Feed("http://example.org", blog, localAuthor, 0);
+	private final BdfDictionary feedDict = new BdfDictionary();
+
+	private final FeedManagerImpl feedManager =
+			new FeedManagerImpl(scheduler, ioExecutor, db, contactGroupFactory,
+					clientHelper, blogManager, blogPostFactory, feedFactory,
+					SocketFactory.getDefault(), clock, noDnsLookups);
+
+	@Test
+	public void testEmptyFetchFeed() throws Exception {
+		BdfList feedList = new BdfList();
+		expectGetFeeds(feedList);
+		expectStoreFeed(feedList);
+		feedManager.fetchFeeds();
+	}
+
+	@Test
+	public void testFetchFeedIoException() throws Exception {
+		final BdfDictionary feedDict= new BdfDictionary();
+		BdfList feedList = BdfList.of(feedDict);
+
+		expectGetFeeds(feedList);
+		context.checking(new Expectations() {{
+			oneOf(noDnsLookups).lookup("example.org");
+			will(throwException(new UnknownHostException()));
+		}});
+		expectStoreFeed(feedList);
+
+		feedManager.fetchFeeds();
+	}
+
+	private void expectGetLocalGroup() {
+		context.checking(new Expectations() {{
+			oneOf(contactGroupFactory).createLocalGroup(CLIENT_ID);
+			will(returnValue(localGroup));
+		}});
+	}
+
+	private void expectGetFeeds(final BdfList feedList) throws Exception {
+		final Transaction txn = new Transaction(null, true);
+		final BdfDictionary feedsDict =
+				BdfDictionary.of(new BdfEntry(KEY_FEEDS, feedList));
+		expectGetLocalGroup();
+		context.checking(new Expectations() {{
+			oneOf(db).startTransaction(true);
+			will(returnValue(txn));
+			oneOf(clientHelper).getGroupMetadataAsDictionary(txn, localGroupId);
+			will(returnValue(feedsDict));
+			if (feedList.size() == 1) {
+				oneOf(feedFactory).createFeed(feedDict);
+				will(returnValue(feed));
+			}
+			oneOf(db).commitTransaction(txn);
+			oneOf(db).endTransaction(txn);
+		}});
+	}
+
+	private void expectStoreFeed(final BdfList feedList) throws Exception {
+		final BdfDictionary feedDict =
+				BdfDictionary.of(new BdfEntry(KEY_FEEDS, feedList));
+		expectGetLocalGroup();
+		context.checking(new Expectations() {{
+			oneOf(clientHelper).mergeGroupMetadata(localGroupId, feedDict);
+			if (feedList.size() == 1) {
+				oneOf(feedFactory).feedToBdfDictionary(feed);
+				will(returnValue(feedList.getDictionary(0)));
+			}
+		}});
+	}
+
+}