diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/parser/CityGmlParser.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/parser/CityGmlParser.java
index e5a1b3b3cafbb84016d1d62d87d963d10e4aec10..bdc2454adaa7ee4b11db76ed041f7ad86dd9bd1e 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/parser/CityGmlParser.java
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/parser/CityGmlParser.java
@@ -204,26 +204,46 @@ public class CityGmlParser {
 		CityGMLContext context = getContext();
 
 		if (config.getValidate()) {
-			//TODO: Think of something to validate Inputstream
+			//TODO: Think of something to XML-validate Inputstream
+
+			//XML validation requires looking at nesting of tags
+			//not a problem for small files, but big files will run into memory limit and crash
+			// Maybe do it dirty by writing stream to temp file and passing it to parseCityGmlFile()?
 			throw new InvalidGmlFileException("Invalid GML File.");
 		}
 
 		try {
-			parseEpsgCodeFromStream(is, config);
+			BufferedInputStream bis = new BufferedInputStream(is);
+			readEpsgCodeFromInputStream(bis,config);
 			CityGMLInputFactory in = context.createCityGMLInputFactory()
 					.withChunking(ChunkOptions.chunkByProperties(chunkProperties).skipCityModel(false));
-			try(ObservedInputStream ois = new ObservedInputStream(is, is.available())){
+			try(ObservedInputStream ois = new ObservedInputStream(bis, bis.available())){
 				if (l != null){
 					ois.addListener(l::updateProgress);
 				}
 				return readAndKeepFeatures(config, Path.of(""), in, ois);
 			}
-		} catch (CityGMLReadException | IOException | ParserConfigurationException | SAXException e) {
-			logger.error(e);
+		} catch (CityGMLReadException | IOException e) {
 			throw new CityGmlParseException("Failed to read CityGML file", e);
 		}
 	}
 
+	private static void readEpsgCodeFromInputStream(BufferedInputStream bis, ParserConfiguration config) throws CityGmlParseException {
+		try{
+			// Mark start position of GML-"file"
+			bis.mark(Integer.MAX_VALUE);
+			// Buffer the first 10000 chars of the Stream, EPSG/envelope info should be found within that range
+			int peekingWidth = Math.min(10000, bis.available());
+			byte[] buf = new byte[peekingWidth];
+			bis.read(buf, 0, peekingWidth);
+			bis.reset();
+			parseEpsgCodeFromBuffer(buf, config);
+		} catch (ParserConfigurationException | SAXException | IOException e) {
+			throw new CityGmlParseException("Failed to read CityGML file", e);
+		}
+
+    }
+
 	public static void streamCityGml(String file, ParserConfiguration config, CityGmlConsumer cityObjectConsumer,
 			String outputFile) throws CityGmlParseException {
 		Path f = Paths.get(file);
@@ -438,6 +458,31 @@ public class CityGmlParser {
 			logEpsgParseError(e);
 		}
 	}
+
+	private static void parseEpsgCodeFromBuffer(byte[] buffer, ParserConfiguration config)
+			throws ParserConfigurationException, SAXException {
+		InputStream is = new ByteArrayInputStream(buffer);
+		SAXParser parser = FACTORY.newSAXParser();
+		CityGmlHandler handler = new CityGmlHandler();
+		try {
+			parser.parse(new InputSource(is), handler);
+		} catch (EnvelopeFoundException e) {
+			try {
+				parseCoordinateSystem(config, handler);
+
+			} catch (Exception e2) {
+				logEpsgParseError(e2);
+			}
+		}catch (SAXParseException spe){
+			// suppress XML document structure warning
+			if (!spe.getMessage().matches("XML document structures must start and end within the same entity.")){
+				logEpsgParseError(spe);
+			}
+		}catch (Exception e) {
+			logEpsgParseError(e);
+		}
+	}
+
 	private static void logEpsgParseError(Exception e){
 		logger.debug("Exception while parsing for EPSG code", e);
 		if (logger.isWarnEnabled()) {