diff --git a/libcorpus2/CMakeLists.txt b/libcorpus2/CMakeLists.txt
index 70d022d7b47e3ae9dafd6b218adc523909064cfb..bb21452b1febf8c19b29dad0c705688b6b1748b9 100644
--- a/libcorpus2/CMakeLists.txt
+++ b/libcorpus2/CMakeLists.txt
@@ -3,7 +3,7 @@ PROJECT(corpus2)
 
 set(corpus2_ver_major "1")
 set(corpus2_ver_minor "0")
-set(corpus2_ver_patch "9")
+set(corpus2_ver_patch "10")
 
 
 if(NOT LIBCORPUS2_SRC_DATA_DIR)
diff --git a/libcorpus2/io/reader.h b/libcorpus2/io/reader.h
index 417497d637d8600f37d9476730e2323bd10802d4..2c2ddecc11aecffdc7821ef9f9655d693d358b20 100644
--- a/libcorpus2/io/reader.h
+++ b/libcorpus2/io/reader.h
@@ -101,6 +101,12 @@ public:
 	 */
 	virtual std::string get_option(const std::string& option) const;
 
+	/**
+	 * Check if the reader is valid, should throw if not. Called after
+	 * all set_options during factory reader creation.
+	 */
+	virtual void validate() {}
+
 	/**
 	 * Tagset accesor
 	 */
@@ -221,6 +227,7 @@ T* stream_reader_creator(const Tagset& tagset, std::istream& is,
 	foreach (const string_range& sr, params) {
 		reader->set_option(boost::copy_range<std::string>(sr));
 	}
+	reader->validate();
 	return reader;
 }
 
@@ -236,6 +243,7 @@ T* path_reader_creator(const Tagset& tagset, const std::string& path,
 	foreach (const string_range& sr, params) {
 		reader->set_option(boost::copy_range<std::string>(sr));
 	}
+	reader->validate();
 	return reader;
 }